mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-16 20:10:18 +00:00
Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e3acdf1802 | |||
| f81d28dd5f | |||
| 8e02a702f1 | |||
| cb7a343208 | |||
| 3be8ddae74 | |||
| 9cd1862300 | |||
| 81fdf50217 | |||
| 554d47e301 | |||
| b66ae7ad77 | |||
| 4ddced8e26 | |||
| d003047a6c | |||
| 1e4a78c812 | |||
| 2a3ffd707e | |||
| aca076381b | |||
| 12ac227d2d | |||
| e235280253 | |||
| 0da0c4e894 | |||
| 47f1509ecc | |||
| ae8ef0dd3c | |||
| 687f9e95fa | |||
| 6dbe5f024f | |||
| a39a276299 | |||
| 9f57e5685f | |||
| bdcba202c9 | |||
| 3c48dcb2a6 | |||
| b59d94d0a9 | |||
| db74b55c41 | |||
| 37b5af235a | |||
| e2b05ce575 | |||
| 49851ee3d7 | |||
|
|
cd596cc66d | ||
|
|
5667ae8095 | ||
| f29996aac8 | |||
| 32613bacc6 | |||
| cf9dba0ecc | |||
| a8c4879769 | |||
| f083e94c05 | |||
| c332413e5a | |||
| c9f3d99cd7 | |||
| cf3d07a20d | |||
| e40548e558 | |||
| 4cd8e823c6 | |||
| 9c7faec124 | |||
| 2856880a6e | |||
|
|
5445fdbfa5 | ||
| ba53d0c75d | |||
| 78f6cc5a97 | |||
| 6ab7c6f9d9 | |||
| cb6b33727e | |||
| bc4a2235c5 | |||
| 300f94fd48 | |||
| 40617ad9c8 | |||
| bea056bba3 | |||
| 9a33451f88 | |||
| c4659b558f | |||
| 5a30a07554 | |||
| b064becb8a | |||
| 463d5252bd | |||
| 8b5da90e28 | |||
| febd6ce63c | |||
| 8df8b87d54 | |||
| c882717bcc | |||
| 4aa5924615 | |||
| 2b8e728559 | |||
| 90ad34f114 | |||
| dbe2607994 | |||
| 692b668f92 | |||
| f2322e3e57 | |||
| ae002ead43 | |||
| 4197e13c54 | |||
| e09ea9a9b4 | |||
| 2a32654d57 | |||
| 0fff553ce1 | |||
| 33a1701f5b | |||
| f9a9f958ba | |||
| f686be0271 | |||
| 91307f3ebf | |||
| 8e64205f53 | |||
| 5434df1f02 | |||
| e56199ac9f | |||
| 3e199c6944 | |||
| b43d9aefb9 | |||
| fe133bbde0 | |||
| 332fe95adf | |||
| 1f416d4a28 | |||
| e626d8b5cc | |||
| b906d605f4 | |||
| d3584e793c | |||
| f71ac51461 | |||
| 5fe8cf948a | |||
| 85ea101641 | |||
| dc3ecec5c7 | |||
| ebd5e1a37b | |||
| 3da2e4fffb | |||
| 9aea59b44b | |||
| 7bab96a9cd |
72
CHANGELOG.md
72
CHANGELOG.md
@@ -1,9 +1,79 @@
|
||||
# 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
|
||||
|
||||
* `Versions`:
|
||||
* `MicroUtils`: `0.16.6` -> `0.16.8`
|
||||
* `Ktor`: `2.2.2` -> `2.2.3`
|
||||
* `BehaviourBuilder`:
|
||||
* Fixes in `BehaviourContext.onEditedContentMessage` - now it will trigger callback on channel post edits too
|
||||
|
||||
## 5.0.1
|
||||
|
||||
* `Versions`:
|
||||
* `MicroUtils`: `0.16.4` -> `0.16.6`
|
||||
* `Ktor`: `2.2.1` -> `2.2.2`
|
||||
* `Core`:
|
||||
* Fixes in `SendMediaGroup` request
|
||||
* Fixes in `SetChatAdministratorCustomTitle` request (thanks to [@madhead](https://github.com/madhead))
|
||||
|
||||
## 5.0.0
|
||||
|
||||
[Bot API 6.4](https://core.telegram.org/bots/api-changelog#december-30-2022) support!
|
||||
|
||||
* Long-polling improvements
|
||||
|
||||
## 4.2.4
|
||||
|
||||
* `Core`:
|
||||
* Fixes in webhook parts adapter
|
||||
* `BehaviourBuilderWithFSM`:
|
||||
* Fixes in `DefaultBehaviourContextWithFSM`
|
||||
|
||||
## 4.2.3
|
||||
|
||||
* `Versions`:
|
||||
* `MicroUtils`: `0.16.2` -> `0.16.4`
|
||||
* `Core`:
|
||||
* Simplify default `RequestsLimiter` (`ExceptionsOnlyLimiter`) (thanks to [@y9san9](https://github.com/y9san9) for help)
|
||||
|
||||
## 4.2.2
|
||||
|
||||
* `Versions`:
|
||||
* `MicroUtils`: `0.16.0` -> `0.16.2`
|
||||
* `Core`:
|
||||
* Fix of [#694](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/694): add opportunity to create `ChatId` and `ChatIdWithThreadId` from `IdChatIdentifier`
|
||||
|
||||
## 4.2.1
|
||||
|
||||
* `Versions`:
|
||||
* `MicroUtils`: `0.15.0` -> `0.16.0`
|
||||
* `Ktor`: `2.1.3` -> `2.2.1`
|
||||
* `Utils`:
|
||||
* Improve support of `makeLinkToMessage` extensions
|
||||
|
||||
## 4.2.0
|
||||
|
||||
* `Versions`:
|
||||
* `Kotlin`: `1.7.21` -> `1.7.22`
|
||||
* `MicroUtils`: `0.14.4` -> `0.15.0`
|
||||
|
||||
## 4.1.3
|
||||
|
||||
* `Versions`:
|
||||
* `Kotlin`: `1.7.21` -> `1.7.22`
|
||||
* `MicroUtils`: `0.14.2` -> `0.14.4`
|
||||
* `Core`:
|
||||
* `ContentMessage`, `CommonMessage`, `PossiblyMediaGroupMessage` and `PossiblySentViaBotCommonMessage` got `out`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#november-5-2022)
|
||||
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#february-3-2023)
|
||||
|
||||
| Docs | [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
||||
|:---:|:---:|
|
||||
|
||||
@@ -20,6 +20,7 @@ allprojects {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
google()
|
||||
maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" }
|
||||
}
|
||||
if (it != rootProject.findProject("docs")) {
|
||||
tasks.whenTaskAdded { task ->
|
||||
|
||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=4.1.3
|
||||
library_version=5.1.0
|
||||
|
||||
@@ -8,12 +8,12 @@ javax-activation = "1.1.1"
|
||||
|
||||
korlibs = "3.4.0"
|
||||
uuid = "0.6.0"
|
||||
ktor = "2.1.3"
|
||||
ktor = "2.2.3"
|
||||
|
||||
ksp = "1.7.21-1.0.8"
|
||||
ksp = "1.7.22-1.0.8"
|
||||
kotlin-poet = "1.12.0"
|
||||
|
||||
microutils = "0.14.4"
|
||||
microutils = "0.16.8"
|
||||
|
||||
github-release-plugin = "2.4.1"
|
||||
dokka = "1.7.20"
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.CloseForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.CloseGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.ForumTopic
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
|
||||
suspend fun TelegramBot.closeGeneralForumTopic(
|
||||
chatId: ChatIdentifier
|
||||
) = execute(
|
||||
CloseGeneralForumTopic(chatId)
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.closeGeneralForumTopic(
|
||||
chat: Chat
|
||||
) = closeGeneralForumTopic(chat.id)
|
||||
@@ -11,8 +11,8 @@ import dev.inmo.tgbotapi.types.chat.Chat
|
||||
suspend fun TelegramBot.editForumTopic(
|
||||
chatId: ChatIdentifier,
|
||||
messageThreadId: MessageThreadId,
|
||||
name: String,
|
||||
iconEmojiId: CustomEmojiId
|
||||
name: String? = null,
|
||||
iconEmojiId: CustomEmojiId? = null
|
||||
) = execute(
|
||||
EditForumTopic(
|
||||
chatId,
|
||||
@@ -25,12 +25,12 @@ suspend fun TelegramBot.editForumTopic(
|
||||
suspend fun TelegramBot.editForumTopic(
|
||||
chat: Chat,
|
||||
messageThreadId: MessageThreadId,
|
||||
name: String,
|
||||
iconEmojiId: CustomEmojiId
|
||||
name: String? = null,
|
||||
iconEmojiId: CustomEmojiId? = null
|
||||
) = editForumTopic(chat.id, messageThreadId, name, iconEmojiId)
|
||||
|
||||
suspend fun TelegramBot.editForumTopic(
|
||||
chatIdentifier: ChatIdentifier,
|
||||
forumTopic: ForumTopic,
|
||||
iconEmojiId: CustomEmojiId = forumTopic.iconEmojiId ?: error("Icon emoji id in forum topic should be presented when edit forum topic basing on other forum topic object")
|
||||
iconEmojiId: CustomEmojiId? = forumTopic.iconEmojiId
|
||||
) = editForumTopic(chatIdentifier, forumTopic.messageThreadId, forumTopic.name, iconEmojiId)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.EditForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.EditGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
||||
import dev.inmo.tgbotapi.types.ForumTopic
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
|
||||
suspend fun TelegramBot.editGeneralForumTopic(
|
||||
chatId: ChatIdentifier,
|
||||
name: String
|
||||
) = execute(
|
||||
EditGeneralForumTopic(
|
||||
chatId,
|
||||
name
|
||||
)
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.editGeneralForumTopic(
|
||||
chat: Chat,
|
||||
name: String
|
||||
) = editGeneralForumTopic(chat.id, name)
|
||||
|
||||
suspend fun TelegramBot.editGeneralForumTopic(
|
||||
chatIdentifier: ChatIdentifier,
|
||||
forumTopic: ForumTopic,
|
||||
) = editGeneralForumTopic(chatIdentifier, forumTopic.name)
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.CloseForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.CloseGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.HideGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.ForumTopic
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
|
||||
suspend fun TelegramBot.hideGeneralForumTopic(
|
||||
chatId: ChatIdentifier
|
||||
) = execute(
|
||||
HideGeneralForumTopic(chatId)
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.hideGeneralForumTopic(
|
||||
chat: Chat
|
||||
) = hideGeneralForumTopic(chat.id)
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.ReopenForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.ReopenGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.ForumTopic
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
|
||||
suspend fun TelegramBot.reopenGeneralForumTopic(
|
||||
chatId: ChatIdentifier
|
||||
) = execute(
|
||||
ReopenGeneralForumTopic(chatId)
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.reopenGeneralForumTopic(
|
||||
chat: Chat
|
||||
) = reopenGeneralForumTopic(chat.id)
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.CloseForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.CloseGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.HideGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.requests.chat.forum.UnhideGeneralForumTopic
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.ForumTopic
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
|
||||
suspend fun TelegramBot.unhideGeneralForumTopic(
|
||||
chatId: ChatIdentifier
|
||||
) = execute(
|
||||
UnhideGeneralForumTopic(chatId)
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.unhideGeneralForumTopic(
|
||||
chat: Chat
|
||||
) = unhideGeneralForumTopic(chat.id)
|
||||
@@ -14,27 +14,31 @@ suspend fun TelegramBot.restrictChatMember(
|
||||
chatId: ChatIdentifier,
|
||||
userId: UserId,
|
||||
untilDate: TelegramDate? = null,
|
||||
permissions: ChatPermissions = ChatPermissions()
|
||||
) = execute(RestrictChatMember(chatId, userId, untilDate, permissions))
|
||||
permissions: ChatPermissions = ChatPermissions(),
|
||||
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
) = execute(RestrictChatMember(chatId, userId, untilDate, permissions, useIndependentChatPermissions))
|
||||
|
||||
suspend fun TelegramBot.restrictChatMember(
|
||||
chat: PublicChat,
|
||||
userId: UserId,
|
||||
untilDate: TelegramDate? = null,
|
||||
permissions: ChatPermissions = ChatPermissions()
|
||||
) = restrictChatMember(chat.id, userId, untilDate, permissions)
|
||||
permissions: ChatPermissions = ChatPermissions(),
|
||||
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
) = restrictChatMember(chat.id, userId, untilDate, permissions, useIndependentChatPermissions)
|
||||
|
||||
suspend fun TelegramBot.restrictChatMember(
|
||||
chatId: IdChatIdentifier,
|
||||
user: User,
|
||||
untilDate: TelegramDate? = null,
|
||||
permissions: ChatPermissions = ChatPermissions()
|
||||
) = restrictChatMember(chatId, user.id, untilDate, permissions)
|
||||
permissions: ChatPermissions = ChatPermissions(),
|
||||
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
) = restrictChatMember(chatId, user.id, untilDate, permissions, useIndependentChatPermissions)
|
||||
|
||||
suspend fun TelegramBot.restrictChatMember(
|
||||
chat: PublicChat,
|
||||
user: User,
|
||||
untilDate: TelegramDate? = null,
|
||||
permissions: ChatPermissions = ChatPermissions()
|
||||
) = restrictChatMember(chat.id, user.id, untilDate, permissions)
|
||||
permissions: ChatPermissions = ChatPermissions(),
|
||||
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(
|
||||
chatId: ChatIdentifier,
|
||||
permissions: ChatPermissions
|
||||
) = execute(SetChatPermissions(chatId, permissions))
|
||||
permissions: ChatPermissions,
|
||||
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
) = execute(SetChatPermissions(chatId, permissions, useIndependentChatPermissions))
|
||||
|
||||
suspend fun TelegramBot.setDefaultChatMembersPermissions(
|
||||
chat: PublicChat,
|
||||
permissions: ChatPermissions
|
||||
) = setDefaultChatMembersPermissions(chat.id, permissions)
|
||||
permissions: ChatPermissions,
|
||||
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
) = setDefaultChatMembersPermissions(chat.id, permissions, useIndependentChatPermissions)
|
||||
|
||||
@@ -379,6 +379,7 @@ suspend inline fun TelegramBot.replyWithAnimation(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -392,6 +393,7 @@ suspend inline fun TelegramBot.replyWithAnimation(
|
||||
thumb,
|
||||
text,
|
||||
parseMode,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -408,6 +410,7 @@ suspend inline fun TelegramBot.reply(
|
||||
animation: AnimationFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -415,12 +418,13 @@ suspend inline fun TelegramBot.reply(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(to.chat, animation, text, parseMode, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(to.chat, animation, text, parseMode, spoilered, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.replyWithAnimation(
|
||||
to: Message,
|
||||
animation: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
thumb: InputFile? = null,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
@@ -434,6 +438,7 @@ suspend inline fun TelegramBot.replyWithAnimation(
|
||||
animation,
|
||||
thumb,
|
||||
entities,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -449,6 +454,7 @@ suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
animation: AnimationFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -456,7 +462,7 @@ suspend inline fun TelegramBot.reply(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(to.chat, animation, entities, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(to.chat, animation, entities, spoilered, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
// Audio
|
||||
@@ -608,64 +614,70 @@ suspend inline fun TelegramBot.replyWithPhoto(
|
||||
fileId: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(to.chat, fileId, text, parseMode, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(to.chat, fileId, text, parseMode, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
photo: Photo,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(to.chat, photo, text, parseMode, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(to.chat, photo, text, parseMode, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
photoSize: PhotoSize,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(to.chat, photoSize, text, parseMode, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(to.chat, photoSize, text, parseMode, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
suspend inline fun TelegramBot.replyWithPhoto(
|
||||
to: Message,
|
||||
fileId: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(to.chat, fileId, entities, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(to.chat, fileId, entities, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
photo: Photo,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(to.chat, photo, entities, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(to.chat, photo, entities, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
photoSize: PhotoSize,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(to.chat, photoSize, entities, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(to.chat, photoSize, entities, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
// Sticker
|
||||
@@ -697,6 +709,7 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -704,24 +717,26 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(to.chat, video, thumb, text, parseMode, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(to.chat, video, thumb, text, parseMode, spoilered, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
video: VideoFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(to.chat, video, text, parseMode, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(to.chat, video, text, parseMode, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.replyWithVideo(
|
||||
to: Message,
|
||||
video: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -729,17 +744,18 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(to.chat, video, thumb, entities, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(to.chat, video, thumb, entities, spoilered, duration, width, height, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
video: VideoFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(to.chat, video, entities, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(to.chat, video, entities, spoilered, to.threadIdOrNull, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
// VideoNotes
|
||||
|
||||
@@ -410,6 +410,7 @@ suspend inline fun TelegramBot.replyWithAnimation(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -424,6 +425,7 @@ suspend inline fun TelegramBot.replyWithAnimation(
|
||||
thumb,
|
||||
text,
|
||||
parseMode,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -441,6 +443,7 @@ suspend inline fun TelegramBot.reply(
|
||||
animation: AnimationFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -449,13 +452,14 @@ suspend inline fun TelegramBot.reply(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(toChatId, animation, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(toChatId, animation, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.replyWithAnimation(
|
||||
toChatId: IdChatIdentifier,
|
||||
toMessageId: MessageId,
|
||||
animation: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
thumb: InputFile? = null,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
@@ -470,6 +474,7 @@ suspend inline fun TelegramBot.replyWithAnimation(
|
||||
animation,
|
||||
thumb,
|
||||
entities,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -486,6 +491,7 @@ suspend inline fun TelegramBot.reply(
|
||||
toMessageId: MessageId,
|
||||
animation: AnimationFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -494,7 +500,7 @@ suspend inline fun TelegramBot.reply(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(toChatId, animation, entities, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(toChatId, animation, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
// Audio
|
||||
@@ -671,12 +677,13 @@ suspend inline fun TelegramBot.replyWithPhoto(
|
||||
fileId: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(toChatId, fileId, text, parseMode, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(toChatId, fileId, text, parseMode, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
toChatId: IdChatIdentifier,
|
||||
@@ -684,12 +691,13 @@ suspend inline fun TelegramBot.reply(
|
||||
photo: Photo,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(toChatId, photo, text, parseMode, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(toChatId, photo, text, parseMode, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
toChatId: IdChatIdentifier,
|
||||
@@ -697,12 +705,13 @@ suspend inline fun TelegramBot.reply(
|
||||
photoSize: PhotoSize,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(toChatId, photoSize, text, parseMode, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(toChatId, photoSize, text, parseMode, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
suspend inline fun TelegramBot.replyWithPhoto(
|
||||
@@ -710,36 +719,39 @@ suspend inline fun TelegramBot.replyWithPhoto(
|
||||
toMessageId: MessageId,
|
||||
fileId: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(toChatId, fileId, entities, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(toChatId, fileId, entities, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
toChatId: IdChatIdentifier,
|
||||
toMessageId: MessageId,
|
||||
photo: Photo,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(toChatId, photo, entities, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(toChatId, photo, entities, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
toChatId: IdChatIdentifier,
|
||||
toMessageId: MessageId,
|
||||
photoSize: PhotoSize,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(toChatId, photoSize, entities, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(toChatId, photoSize, entities, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
// Sticker
|
||||
@@ -776,6 +788,7 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -784,7 +797,7 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(toChatId, video, thumb, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(toChatId, video, thumb, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
toChatId: IdChatIdentifier,
|
||||
@@ -792,12 +805,13 @@ suspend inline fun TelegramBot.reply(
|
||||
video: VideoFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(toChatId, video, text, parseMode, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(toChatId, video, text, parseMode, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.replyWithVideo(
|
||||
toChatId: IdChatIdentifier,
|
||||
@@ -805,6 +819,7 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
video: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -813,19 +828,20 @@ suspend inline fun TelegramBot.replyWithVideo(
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(toChatId, video, thumb, entities, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(toChatId, video, thumb, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
toChatId: IdChatIdentifier,
|
||||
toMessageId: MessageId,
|
||||
video: VideoFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = toChatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(toChatId, video, entities, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(toChatId, video, entities, spoilered, threadId, disableNotification, protectContent, toMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
// VideoNotes
|
||||
|
||||
@@ -3,104 +3,129 @@ package dev.inmo.tgbotapi.extensions.api.send
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.send.SendAction
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.actions.*
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.threadId
|
||||
|
||||
suspend fun TelegramBot.sendBotAction(
|
||||
chatId: ChatIdentifier,
|
||||
action: BotAction
|
||||
action: BotAction,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = execute(
|
||||
SendAction(chatId, action)
|
||||
SendAction(chatId, action, threadId)
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.sendBotAction(
|
||||
chat: Chat,
|
||||
action: BotAction
|
||||
) = sendBotAction(chat.id, action)
|
||||
action: BotAction,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat.id, action, threadId)
|
||||
|
||||
|
||||
suspend fun TelegramBot.sendActionTyping(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, TypingAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, TypingAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadPhoto(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, UploadPhotoAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, UploadPhotoAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionRecordVideo(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, RecordVideoAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, RecordVideoAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadVideo(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, UploadVideoAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, UploadVideoAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionRecordVoice(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, RecordVoiceAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, RecordVoiceAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadVoice(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, UploadVoiceAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, UploadVoiceAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadDocument(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, UploadDocumentAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, UploadDocumentAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionFindLocation(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, FindLocationAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, FindLocationAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionRecordVideoNote(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, RecordVideoNoteAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, RecordVideoNoteAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadVideoNote(
|
||||
chatId: ChatIdentifier
|
||||
) = sendBotAction(chatId, UploadVideoNoteAction)
|
||||
chatId: ChatIdentifier,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
) = sendBotAction(chatId, UploadVideoNoteAction, threadId)
|
||||
|
||||
|
||||
suspend fun TelegramBot.sendActionTyping(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, TypingAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, TypingAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadPhoto(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, UploadPhotoAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, UploadPhotoAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionRecordVideo(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, RecordVideoAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, RecordVideoAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadVideo(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, UploadVideoAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, UploadVideoAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionRecordVoice(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, RecordVoiceAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, RecordVoiceAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadVoice(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, UploadVoiceAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, UploadVoiceAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadDocument(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, UploadDocumentAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, UploadDocumentAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionFindLocation(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, FindLocationAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, FindLocationAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionRecordVideoNote(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, RecordVideoNoteAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, RecordVideoNoteAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionUploadVideoNote(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, UploadVideoNoteAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, UploadVideoNoteAction, threadId)
|
||||
|
||||
suspend fun TelegramBot.sendActionChooseStickerAction(
|
||||
chat: Chat
|
||||
) = sendBotAction(chat, ChooseStickerAction)
|
||||
chat: Chat,
|
||||
threadId: MessageThreadId? = chat.id.threadId
|
||||
) = sendBotAction(chat, ChooseStickerAction, threadId)
|
||||
|
||||
|
||||
@@ -38,13 +38,14 @@ suspend fun <T> TelegramBot.withAction(
|
||||
suspend fun <T> TelegramBot.withAction(
|
||||
chatId: IdChatIdentifier,
|
||||
action: BotAction,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
block: TelegramBotActionCallback<T>
|
||||
): T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(
|
||||
SendAction(chatId, action),
|
||||
SendAction(chatId, action, threadId),
|
||||
block
|
||||
)
|
||||
}
|
||||
@@ -53,6 +54,7 @@ suspend fun <T> TelegramBot.withAction(
|
||||
suspend fun <T> TelegramBot.withAction(
|
||||
chat: Chat,
|
||||
action: BotAction,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
block: TelegramBotActionCallback<T>
|
||||
): T {
|
||||
contract {
|
||||
@@ -61,163 +63,164 @@ suspend fun <T> TelegramBot.withAction(
|
||||
return withAction(
|
||||
chat.id,
|
||||
action,
|
||||
threadId,
|
||||
block
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withTypingAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withTypingAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, TypingAction, block)
|
||||
return withAction(chatId, TypingAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, UploadPhotoAction, block)
|
||||
return withAction(chatId, UploadPhotoAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withRecordVideoAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withRecordVideoAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, RecordVideoAction, block)
|
||||
return withAction(chatId, RecordVideoAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadVideoAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadVideoAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, UploadVideoAction, block)
|
||||
return withAction(chatId, UploadVideoAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withRecordVoiceAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withRecordVoiceAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, RecordVoiceAction, block)
|
||||
return withAction(chatId, RecordVoiceAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadVoiceAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadVoiceAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, UploadVoiceAction, block)
|
||||
return withAction(chatId, UploadVoiceAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, UploadDocumentAction, block)
|
||||
return withAction(chatId, UploadDocumentAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withFindLocationAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withFindLocationAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, FindLocationAction, block)
|
||||
return withAction(chatId, FindLocationAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, RecordVideoNoteAction, block)
|
||||
return withAction(chatId, RecordVideoNoteAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, UploadVideoNoteAction, block)
|
||||
return withAction(chatId, UploadVideoNoteAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withChooseStickerAction(chatId: IdChatIdentifier, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withChooseStickerAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chatId, ChooseStickerAction, block)
|
||||
return withAction(chatId, ChooseStickerAction, threadId, block)
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withTypingAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, TypingAction, block)
|
||||
return withAction(chat, TypingAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, UploadPhotoAction, block)
|
||||
return withAction(chat, UploadPhotoAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withRecordVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withRecordVideoAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, RecordVideoAction, block)
|
||||
return withAction(chat, RecordVideoAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadVideoAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, UploadVideoAction, block)
|
||||
return withAction(chat, UploadVideoAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withRecordVoiceAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withRecordVoiceAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, RecordVoiceAction, block)
|
||||
return withAction(chat, RecordVoiceAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadVoiceAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadVoiceAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, UploadVoiceAction, block)
|
||||
return withAction(chat, UploadVoiceAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, UploadDocumentAction, block)
|
||||
return withAction(chat, UploadDocumentAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withFindLocationAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, FindLocationAction, block)
|
||||
return withAction(chat, FindLocationAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, RecordVideoNoteAction, block)
|
||||
return withAction(chat, RecordVideoNoteAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, UploadVideoNoteAction, block)
|
||||
return withAction(chat, UploadVideoNoteAction, threadId, block)
|
||||
}
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun <T> TelegramBot.withChooseStickerAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||
suspend fun <T> TelegramBot.withChooseStickerAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId,block: TelegramBotActionCallback<T>) : T {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return withAction(chat, ChooseStickerAction, block)
|
||||
return withAction(chat, ChooseStickerAction, threadId, block)
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ suspend fun TelegramBot.send(
|
||||
animation: AnimationFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -65,7 +66,7 @@ suspend fun TelegramBot.send(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chatId, animation, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chatId, animation, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendAnimation] request
|
||||
@@ -77,6 +78,7 @@ suspend fun TelegramBot.send(
|
||||
animation: AnimationFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -86,7 +88,7 @@ suspend fun TelegramBot.send(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chat, animation, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chat, animation, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendAnimation] request
|
||||
@@ -97,6 +99,7 @@ suspend fun TelegramBot.send(
|
||||
chatId: ChatIdentifier,
|
||||
animation: AnimationFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -106,7 +109,7 @@ suspend fun TelegramBot.send(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chatId, animation, entities, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chatId, animation, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendAnimation] request
|
||||
@@ -117,6 +120,7 @@ suspend fun TelegramBot.send(
|
||||
chat: Chat,
|
||||
animation: AnimationFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -126,7 +130,7 @@ suspend fun TelegramBot.send(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chat, animation, entities, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chat, animation, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendAudio] request
|
||||
@@ -688,13 +692,14 @@ suspend fun TelegramBot.send(
|
||||
photo: Photo,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photo, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photo, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -706,13 +711,14 @@ suspend fun TelegramBot.send(
|
||||
photo: Photo,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat, photo, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat, photo, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -724,13 +730,14 @@ suspend fun TelegramBot.send(
|
||||
photoSize: PhotoSize,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photoSize, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photoSize, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -742,13 +749,14 @@ suspend fun TelegramBot.send(
|
||||
photoSize: PhotoSize,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat, photoSize, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat, photoSize, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -759,13 +767,14 @@ suspend inline fun TelegramBot.send(
|
||||
chatId: ChatIdentifier,
|
||||
photo: Photo,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photo, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photo, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -776,13 +785,14 @@ suspend inline fun TelegramBot.send(
|
||||
chat: Chat,
|
||||
photo: Photo,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat, photo, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat, photo, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -793,13 +803,14 @@ suspend inline fun TelegramBot.send(
|
||||
chatId: ChatIdentifier,
|
||||
photoSize: PhotoSize,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photoSize, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photoSize, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendPhoto] request
|
||||
@@ -810,13 +821,14 @@ suspend inline fun TelegramBot.send(
|
||||
chat: Chat,
|
||||
photoSize: PhotoSize,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat, photoSize, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat, photoSize, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendRegularPoll] request
|
||||
@@ -1357,13 +1369,14 @@ suspend fun TelegramBot.send(
|
||||
video: VideoFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chatId, video, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chatId, video, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendVideo] request
|
||||
@@ -1375,13 +1388,14 @@ suspend fun TelegramBot.send(
|
||||
video: VideoFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chat, video, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chat, video, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendVideo] request
|
||||
@@ -1392,13 +1406,14 @@ suspend inline fun TelegramBot.send(
|
||||
chatId: ChatIdentifier,
|
||||
video: VideoFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chatId, video, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chatId, video, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendVideo] request
|
||||
@@ -1409,13 +1424,14 @@ suspend inline fun TelegramBot.send(
|
||||
chat: Chat,
|
||||
video: VideoFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chat, video, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chat, video, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* Will execute [sendVideoNote] request
|
||||
|
||||
@@ -23,6 +23,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -39,6 +40,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
thumb,
|
||||
text,
|
||||
parseMode,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -60,6 +62,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
animation: AnimationFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -70,7 +73,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(
|
||||
chatId, animation.fileId, animation.thumb ?.fileId, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup
|
||||
chatId, animation.fileId, animation.thumb ?.fileId, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -83,6 +86,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -92,7 +96,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chat.id, animation, thumb, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chat.id, animation, thumb, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -103,6 +107,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
animation: AnimationFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -112,7 +117,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chat.id, animation, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chat.id, animation, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
/**
|
||||
@@ -124,6 +129,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
animation: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -139,6 +145,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
animation,
|
||||
thumb,
|
||||
entities,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -159,6 +166,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
chatId: ChatIdentifier,
|
||||
animation: AnimationFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -169,7 +177,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(
|
||||
chatId, animation.fileId, animation.thumb ?.fileId, entities, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup
|
||||
chatId, animation.fileId, animation.thumb ?.fileId, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -181,6 +189,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
animation: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -190,7 +199,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chat.id, animation, thumb, entities, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chat.id, animation, thumb, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -200,6 +209,7 @@ suspend fun TelegramBot.sendAnimation(
|
||||
chat: Chat,
|
||||
animation: AnimationFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -209,4 +219,4 @@ suspend fun TelegramBot.sendAnimation(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendAnimation(chat.id, animation, entities, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendAnimation(chat.id, animation, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
@@ -22,6 +22,7 @@ suspend fun TelegramBot.sendPhoto(
|
||||
fileId: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
@@ -34,6 +35,7 @@ suspend fun TelegramBot.sendPhoto(
|
||||
fileId,
|
||||
text,
|
||||
parseMode,
|
||||
spoilered,
|
||||
threadId,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
@@ -52,13 +54,14 @@ suspend fun TelegramBot.sendPhoto(
|
||||
fileId: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat.id, fileId, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat.id, fileId, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -69,13 +72,14 @@ suspend fun TelegramBot.sendPhoto(
|
||||
photo: Photo,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photo.biggest() ?.fileId ?: error("Photo content must not be empty"), text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photo.biggest() ?.fileId ?: error("Photo content must not be empty"), text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -86,13 +90,14 @@ suspend fun TelegramBot.sendPhoto(
|
||||
photo: Photo,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat.id, photo, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat.id, photo, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -103,13 +108,14 @@ suspend fun TelegramBot.sendPhoto(
|
||||
photoSize: PhotoSize,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photoSize.fileId, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photoSize.fileId, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -120,13 +126,14 @@ suspend fun TelegramBot.sendPhoto(
|
||||
photoSize: PhotoSize,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat.id, photoSize, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat.id, photoSize, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
/**
|
||||
@@ -137,6 +144,7 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chatId: ChatIdentifier,
|
||||
fileId: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
@@ -148,6 +156,7 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chatId,
|
||||
fileId,
|
||||
entities,
|
||||
spoilered,
|
||||
threadId,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
@@ -165,13 +174,14 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chat: Chat,
|
||||
fileId: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat.id, fileId, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat.id, fileId, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -181,13 +191,14 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chatId: ChatIdentifier,
|
||||
photo: Photo,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photo.biggest() ?.fileId ?: error("Photo content must not be empty"), entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photo.biggest() ?.fileId ?: error("Photo content must not be empty"), entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -197,13 +208,14 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chat: Chat,
|
||||
photo: Photo,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat.id, photo, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat.id, photo, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -213,13 +225,14 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chatId: ChatIdentifier,
|
||||
photoSize: PhotoSize,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chatId, photoSize.fileId, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chatId, photoSize.fileId, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -229,10 +242,11 @@ suspend inline fun TelegramBot.sendPhoto(
|
||||
chat: Chat,
|
||||
photoSize: PhotoSize,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendPhoto(chat.id, photoSize, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendPhoto(chat.id, photoSize, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
@@ -23,6 +23,7 @@ suspend fun TelegramBot.sendVideo(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -39,6 +40,7 @@ suspend fun TelegramBot.sendVideo(
|
||||
thumb,
|
||||
text,
|
||||
parseMode,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -61,13 +63,14 @@ suspend fun TelegramBot.sendVideo(
|
||||
video: VideoFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chatId, video.fileId, video.thumb ?.fileId, text, parseMode, video.duration, video.width, video.height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chatId, video.fileId, video.thumb ?.fileId, text, parseMode, spoilered, video.duration, video.width, video.height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -79,6 +82,7 @@ suspend fun TelegramBot.sendVideo(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -88,7 +92,7 @@ suspend fun TelegramBot.sendVideo(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chat.id, video, thumb, text, parseMode, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chat.id, video, thumb, text, parseMode, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
/**
|
||||
@@ -100,13 +104,14 @@ suspend fun TelegramBot.sendVideo(
|
||||
video: VideoFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chat.id, video, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chat.id, video, text, parseMode, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -117,6 +122,7 @@ suspend inline fun TelegramBot.sendVideo(
|
||||
video: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -132,6 +138,7 @@ suspend inline fun TelegramBot.sendVideo(
|
||||
video,
|
||||
thumb,
|
||||
entities,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -153,13 +160,14 @@ suspend inline fun TelegramBot.sendVideo(
|
||||
chatId: ChatIdentifier,
|
||||
video: VideoFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chatId, video.fileId, video.thumb ?.fileId, entities, video.duration, video.width, video.height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chatId, video.fileId, video.thumb ?.fileId, entities, spoilered, video.duration, video.width, video.height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -170,6 +178,7 @@ suspend inline fun TelegramBot.sendVideo(
|
||||
video: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -179,7 +188,7 @@ suspend inline fun TelegramBot.sendVideo(
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chat.id, video, thumb, entities, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chat.id, video, thumb, entities, spoilered, duration, width, height, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
/**
|
||||
@@ -190,10 +199,11 @@ suspend inline fun TelegramBot.sendVideo(
|
||||
chat: Chat,
|
||||
video: VideoFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendVideo(chat.id, video, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
) = sendVideo(chat.id, video, entities, spoilered, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
@@ -10,6 +10,8 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.T
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
@@ -133,6 +135,9 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>()
|
||||
private var actualHandlersList = additionalHandlers + handlers
|
||||
|
||||
protected val statesJobs = mutableMapOf<T, Job>()
|
||||
protected val statesJobsMutex = Mutex()
|
||||
|
||||
override suspend fun launchStateHandling(state: T, handlers: List<CheckableHandlerHolder<in T, T>>): T? {
|
||||
return launchStateHandling(state, handlers, onStateHandlingErrorHandler)
|
||||
}
|
||||
@@ -164,21 +169,49 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
statesManager.endChain(state)
|
||||
}
|
||||
}
|
||||
|
||||
fun Job.enableRemoveOnCompletion(state: T) {
|
||||
invokeOnCompletion {
|
||||
launchSafelyWithoutExceptions {
|
||||
statesJobsMutex.withLock {
|
||||
if (this@enableRemoveOnCompletion === statesJobs[state]) {
|
||||
statesJobs.remove(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statesManager.onStartChain.subscribeSafelyWithoutExceptions(this) {
|
||||
launch { statePerformer(it) }
|
||||
statesJobsMutex.withLock {
|
||||
runCatchingSafely { statesJobs.remove(it) ?.cancel() }
|
||||
|
||||
statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) }
|
||||
}
|
||||
}
|
||||
statesManager.onEndChain.subscribeSafelyWithoutExceptions(this) {
|
||||
statesJobsMutex.withLock {
|
||||
runCatchingSafely { statesJobs.remove(it) ?.cancel() }
|
||||
}
|
||||
updatesFlows.remove(it.context)
|
||||
}
|
||||
statesManager.onChainStateUpdated.subscribeSafelyWithoutExceptions(this) { (old, new) ->
|
||||
statesJobsMutex.withLock {
|
||||
runCatchingSafely { statesJobs.remove(old) ?.cancel() }
|
||||
runCatchingSafely { statesJobs.remove(new) ?.cancel() }
|
||||
statesJobs[new] = launch { statePerformer(new) }.apply { enableRemoveOnCompletion(new) }
|
||||
}
|
||||
if (old.context != new.context) {
|
||||
updatesFlows.remove(old.context)
|
||||
}
|
||||
launch { statePerformer(new) }
|
||||
}
|
||||
statesManager.onEndChain.subscribeSafelyWithoutExceptions(this) {
|
||||
updatesFlows.remove(it.context)
|
||||
}
|
||||
|
||||
statesManager.getActiveStates().forEach {
|
||||
launch { statePerformer(it) }
|
||||
statesJobsMutex.withLock {
|
||||
runCatchingSafely { statesJobs.remove(it) ?.cancel() }
|
||||
|
||||
statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -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.tgbotapi.bot.TelegramBot
|
||||
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.updateshandlers.FlowsUpdatesFilter
|
||||
import kotlinx.coroutines.*
|
||||
@@ -54,6 +55,9 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||
timeoutSeconds: Seconds = 30,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
||||
upstreamUpdatesFlow,
|
||||
@@ -66,7 +70,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||
).run {
|
||||
this to scope.launch {
|
||||
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()),
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||
timeoutSeconds: Seconds = 30,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
) = FlowsUpdatesFilter().let {
|
||||
buildBehaviourWithFSM(
|
||||
@@ -138,7 +145,11 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||
start()
|
||||
longPolling(
|
||||
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.TelegramBot
|
||||
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.utils.telegramBotAPIDefaultUrl
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -42,6 +43,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
testServer: Boolean = false,
|
||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||
timeoutSeconds: Seconds = 30,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): TelegramBot = telegramBot(
|
||||
token,
|
||||
@@ -56,6 +60,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
||||
statesManager,
|
||||
presetHandlers,
|
||||
onStateHandlingErrorHandler,
|
||||
timeoutSeconds,
|
||||
autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions,
|
||||
block
|
||||
)
|
||||
}
|
||||
@@ -81,6 +88,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
testServer: Boolean = false,
|
||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||
timeoutSeconds: Seconds = 30,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): Pair<TelegramBot, Job> {
|
||||
return telegramBot(
|
||||
@@ -95,6 +105,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
||||
statesManager,
|
||||
presetHandlers,
|
||||
onStateHandlingErrorHandler,
|
||||
timeoutSeconds,
|
||||
autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions,
|
||||
block
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.inmo.micro_utils.coroutines.ExceptionHandler
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
||||
import dev.inmo.tgbotapi.types.Seconds
|
||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
@@ -53,6 +54,9 @@ suspend fun TelegramBot.buildBehaviour(
|
||||
suspend fun TelegramBot.buildBehaviourWithLongPolling(
|
||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
timeoutSeconds: Seconds = 30,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
block: BehaviourContextReceiver<Unit>
|
||||
): Job {
|
||||
val behaviourContext = buildBehaviour(
|
||||
@@ -62,6 +66,9 @@ suspend fun TelegramBot.buildBehaviourWithLongPolling(
|
||||
)
|
||||
return longPolling(
|
||||
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.telegramBot
|
||||
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.utils.telegramBotAPIDefaultUrl
|
||||
import kotlinx.coroutines.*
|
||||
@@ -66,6 +67,9 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
testServer: Boolean = false,
|
||||
timeoutSeconds: Seconds = 30,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
block: BehaviourContextReceiver<Unit>
|
||||
): Pair<TelegramBot, Job> {
|
||||
return telegramBot(
|
||||
@@ -77,6 +81,9 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
||||
it to it.buildBehaviourWithLongPolling(
|
||||
scope ?: CoroutineScope(coroutineContext),
|
||||
defaultExceptionsHandler,
|
||||
timeoutSeconds,
|
||||
autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions,
|
||||
block
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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.forum.ForumTopicClosed
|
||||
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.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.abstracts.ChatEventMessage
|
||||
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.lowLevelRiskFeatureMessage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -151,3 +158,34 @@ suspend fun BehaviourContext.waitForumTopicReopened(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitEvents<ForumTopicReopened>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitForumTopicEdited(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitEvents<ForumTopicEdited>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitGeneralForumTopicHidden(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitEvents<GeneralForumTopicHidden>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitGeneralForumTopicUnhidden(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitEvents<GeneralForumTopicUnhidden>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitWriteAccessAllowed(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = 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.forum.ForumTopicClosed
|
||||
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.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.abstracts.ChatEventMessage
|
||||
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.lowLevelRiskFeatureMessage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -148,3 +155,34 @@ suspend fun BehaviourContext.waitForumTopicReopenedEventsMessages(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = 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)
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/@file:Suppress("unused", "UNCHECKED_CAST")
|
||||
|
||||
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
@@ -35,7 +20,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent>
|
||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
||||
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
|
||||
when (it) {
|
||||
is BaseEditMessageUpdate -> (it.editMessageUpdateOrNull() ?.data ?.withContent<T>())
|
||||
is BaseEditMessageUpdate -> (it.data.withContent<T>())
|
||||
else -> null
|
||||
} ?.let(::listOfNotNull)
|
||||
}
|
||||
|
||||
@@ -13,12 +13,19 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||
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.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.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.PrivateEventMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
|
||||
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
|
||||
|
||||
internal suspend inline fun <BC : BehaviourContext, reified T : ChatEvent> BC.onEvent(
|
||||
@@ -575,3 +582,143 @@ suspend fun <BC : BehaviourContext> BC.onForumTopicReopened(
|
||||
markerFactory: MarkerFactory<in ChatEventMessage<ForumTopicReopened>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<ForumTopicReopened>>
|
||||
) = 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.onForumTopicEdited(
|
||||
initialFilter: SimpleFilter<SupergroupEventMessage<ForumTopicEdited>>? = null,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, SupergroupEventMessage<ForumTopicEdited>, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in ChatEventMessage<ForumTopicEdited>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<ForumTopicEdited>>
|
||||
) = 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.onGeneralForumTopicHidden(
|
||||
initialFilter: SimpleFilter<SupergroupEventMessage<GeneralForumTopicHidden>>? = null,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, SupergroupEventMessage<GeneralForumTopicHidden>, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in ChatEventMessage<GeneralForumTopicHidden>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<GeneralForumTopicHidden>>
|
||||
) = 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.onGeneralForumTopicUnhidden(
|
||||
initialFilter: SimpleFilter<SupergroupEventMessage<GeneralForumTopicUnhidden>>? = null,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, SupergroupEventMessage<GeneralForumTopicUnhidden>, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in ChatEventMessage<GeneralForumTopicUnhidden>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<GeneralForumTopicUnhidden>>
|
||||
) = 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.onWriteAccessAllowed(
|
||||
initialFilter: SimpleFilter<SupergroupEventMessage<WriteAccessAllowed>>? = null,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, SupergroupEventMessage<WriteAccessAllowed>, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<WriteAccessAllowed>>
|
||||
) = 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)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.abstracts
|
||||
|
||||
interface SpoilerableData {
|
||||
val spoilered: Boolean
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class KtorRequestsExecutor(
|
||||
client: HttpClient = HttpClient(),
|
||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||
excludeDefaultFactories: Boolean = false,
|
||||
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
|
||||
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter,
|
||||
private val jsonFormatter: Json = nonstrictJsonFormat,
|
||||
private val pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
|
||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||
@@ -51,7 +51,7 @@ class KtorRequestsExecutor(
|
||||
override suspend fun <T : Any> execute(request: Request<T>): T {
|
||||
return runCatchingSafely {
|
||||
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
|
||||
requestsLimiter.limit {
|
||||
requestsLimiter.limit(request) {
|
||||
var result: T? = null
|
||||
lateinit var factoryHandledRequest: KtorCallFactory
|
||||
for (potentialFactory in callsFactories) {
|
||||
@@ -111,7 +111,7 @@ class KtorRequestsExecutorBuilder(
|
||||
var client: HttpClient = HttpClient()
|
||||
var callsFactories: List<KtorCallFactory> = emptyList()
|
||||
var excludeDefaultFactories: Boolean = false
|
||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter
|
||||
var jsonFormatter: Json = nonstrictJsonFormat
|
||||
|
||||
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
||||
|
||||
@@ -1,66 +1,18 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.bot.exceptions.TooMuchRequestsException
|
||||
import dev.inmo.tgbotapi.types.MilliSeconds
|
||||
import dev.inmo.tgbotapi.types.RetryAfterError
|
||||
import io.ktor.client.plugins.ClientRequestException
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
||||
/**
|
||||
* This limiter will limit requests only after getting a [RetryAfterError] or [ClientRequestException] with
|
||||
* [HttpStatusCode.TooManyRequests] status code. Important thing is that in case if some of block has been blocked, all
|
||||
* the others will wait until it will be possible to be called
|
||||
*
|
||||
* @param defaultTooManyRequestsDelay This parameter will be used in case of getting [ClientRequestException] with
|
||||
* [HttpStatusCode.TooManyRequests] as a parameter for delay like it would be [TooMuchRequestsException]. The reason of
|
||||
* it is that in [ClientRequestException] there is no information about required delay between requests
|
||||
* Simple limiter which will lock any request when [TooMuchRequestsExceptions] is thrown and rerun request after lock time
|
||||
*/
|
||||
class ExceptionsOnlyLimiter(
|
||||
private val defaultTooManyRequestsDelay: MilliSeconds = 1000L
|
||||
) : RequestLimiter {
|
||||
private val lockState = MutableStateFlow(false)
|
||||
private suspend fun lock(timeMillis: MilliSeconds) {
|
||||
try {
|
||||
safely {
|
||||
lockState.emit(true)
|
||||
delay(timeMillis)
|
||||
}
|
||||
} finally {
|
||||
lockState.emit(false)
|
||||
}
|
||||
}
|
||||
|
||||
object ExceptionsOnlyLimiter : RequestLimiter {
|
||||
override suspend fun <T> limit(block: suspend () -> T): T {
|
||||
while (true) {
|
||||
lockState.first { !it }
|
||||
var throwable: Throwable? = null
|
||||
val result = safely({
|
||||
throwable = when (it) {
|
||||
is TooMuchRequestsException -> {
|
||||
lock(it.retryAfter.leftToRetry)
|
||||
it
|
||||
}
|
||||
is ClientRequestException -> {
|
||||
if (it.response.status == HttpStatusCode.TooManyRequests) {
|
||||
lock(defaultTooManyRequestsDelay)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
it
|
||||
}
|
||||
else -> throw it
|
||||
}
|
||||
null
|
||||
}) {
|
||||
block()
|
||||
}
|
||||
if (throwable == null) {
|
||||
return result!!
|
||||
}
|
||||
return try {
|
||||
block()
|
||||
} catch (e: TooMuchRequestsException) {
|
||||
delay(e.retryAfter.leftToRetry)
|
||||
limit(block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
object NoLimitsLimiter : RequestLimiter {
|
||||
override suspend fun <T> limit(block: suspend () -> T): T = block()
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
|
||||
interface RequestLimiter {
|
||||
/**
|
||||
* Use limit for working of block (like delay between or after, for example)
|
||||
*/
|
||||
suspend fun <T> limit(block: suspend () -> T): T
|
||||
|
||||
suspend fun <T : Any> limit(request: Request<T>, block: suspend () -> T) = limit(block)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.RGBColor
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@Serializable
|
||||
data class CloseGeneralForumTopic (
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier
|
||||
): ModifyForumRequest, GeneralForumRequest<Boolean> {
|
||||
override fun method(): String = "closeGeneralForumTopic"
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.RGBColor
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@Serializable
|
||||
data class EditForumTopic (
|
||||
@@ -14,12 +10,12 @@ data class EditForumTopic (
|
||||
@SerialName(messageThreadIdField)
|
||||
val messageThreadId: MessageThreadId,
|
||||
@SerialName(nameField)
|
||||
val name: String,
|
||||
val name: String? = null,
|
||||
@SerialName(iconCustomEmojiIdField)
|
||||
val iconEmojiId: CustomEmojiId,
|
||||
val iconEmojiId: CustomEmojiId? = null,
|
||||
): ModifyForumRequest {
|
||||
init {
|
||||
if (name.length !in threadNameLength) {
|
||||
if (name != null && name.length !in threadNameLength) {
|
||||
throw IllegalArgumentException("Thread name must be in $threadNameLength range")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
data class EditGeneralForumTopic (
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
@SerialName(nameField)
|
||||
val name: String
|
||||
): ModifyForumRequest, GeneralForumRequest<Boolean> {
|
||||
init {
|
||||
if (name.length !in threadNameLength) {
|
||||
throw IllegalArgumentException("Thread name must be in $threadNameLength range")
|
||||
}
|
||||
}
|
||||
|
||||
override fun method(): String = "editGeneralForumTopic"
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
|
||||
sealed interface GeneralForumRequest<T : Any> : ForumRequest<T>, ChatRequest
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.RGBColor
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@Serializable
|
||||
data class HideGeneralForumTopic (
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier
|
||||
): ModifyForumRequest, GeneralForumRequest<Boolean> {
|
||||
override fun method(): String = "hideGeneralForumTopic"
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.RGBColor
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@Serializable
|
||||
data class ReopenGeneralForumTopic (
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
): ModifyForumRequest, GeneralForumRequest<Boolean> {
|
||||
override fun method(): String = "reopenGeneralForumTopic"
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.forum
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.RGBColor
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@Serializable
|
||||
data class UnhideGeneralForumTopic (
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier
|
||||
): ModifyForumRequest, GeneralForumRequest<Boolean> {
|
||||
override fun method(): String = "unhideGeneralForumTopic"
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
@@ -16,7 +16,9 @@ data class RestrictChatMember(
|
||||
@SerialName(untilDateField)
|
||||
override val untilDate: TelegramDate? = null,
|
||||
@SerialName(permissionsField)
|
||||
val permissions: ChatPermissions = ChatPermissions()
|
||||
val permissions: ChatPermissions = ChatPermissions(),
|
||||
@SerialName(useIndependentChatPermissionsField)
|
||||
val useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
) : ChatMemberRequest<Boolean>, UntilDate {
|
||||
override fun method(): String = "restrictChatMember"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
|
||||
@@ -18,7 +18,7 @@ data class SetChatAdministratorCustomTitle(
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
get() = Boolean.serializer()
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = RestrictChatMember.serializer()
|
||||
get() = serializer()
|
||||
|
||||
init {
|
||||
if (customTitle.length !in customTitleLength) {
|
||||
|
||||
@@ -12,7 +12,9 @@ data class SetChatPermissions (
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
@SerialName(permissionsField)
|
||||
val permissions: ChatPermissions
|
||||
val permissions: ChatPermissions,
|
||||
@SerialName(useIndependentChatPermissionsField)
|
||||
val useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||
): ChatRequest, SimpleRequest<Boolean> {
|
||||
override fun method(): String = "setChatPermissions"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.inmo.tgbotapi.requests.send
|
||||
|
||||
import dev.inmo.tgbotapi.requests.send.abstracts.OptionallyMessageThreadRequest
|
||||
import dev.inmo.tgbotapi.requests.send.abstracts.SendChatMessageRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.actions.BotAction
|
||||
@@ -14,8 +15,10 @@ data class SendAction(
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
@SerialName(actionField)
|
||||
val action: BotAction
|
||||
): SendChatMessageRequest<Boolean> {
|
||||
val action: BotAction,
|
||||
@SerialName(messageThreadIdField)
|
||||
override val threadId: MessageThreadId? = chatId.threadId
|
||||
): SendChatMessageRequest<Boolean>, OptionallyMessageThreadRequest {
|
||||
override fun method(): String = "sendChatAction"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
get() = Boolean.serializer()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.requests.send.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.SpoilerableData
|
||||
|
||||
interface OptionallyWithSpoilerRequest : SpoilerableData
|
||||
@@ -25,6 +25,7 @@ fun SendAnimation(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -47,6 +48,7 @@ fun SendAnimation(
|
||||
text,
|
||||
parseMode,
|
||||
null,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -73,6 +75,7 @@ fun SendAnimation(
|
||||
animation: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -95,6 +98,7 @@ fun SendAnimation(
|
||||
entities.makeString(),
|
||||
null,
|
||||
entities.toRawMessageEntities(),
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -133,6 +137,8 @@ data class SendAnimationData internal constructor(
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
@SerialName(durationField)
|
||||
override val duration: Long? = null,
|
||||
@SerialName(widthField)
|
||||
@@ -157,7 +163,8 @@ data class SendAnimationData internal constructor(
|
||||
TextableSendMessageRequest<ContentMessage<AnimationContent>>,
|
||||
ThumbedSendMessageRequest<ContentMessage<AnimationContent>>,
|
||||
DuratedSendMessageRequest<ContentMessage<AnimationContent>>,
|
||||
SizedSendMessageRequest<ContentMessage<AnimationContent>>
|
||||
SizedSendMessageRequest<ContentMessage<AnimationContent>>,
|
||||
OptionallyWithSpoilerRequest
|
||||
{
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
|
||||
@@ -37,7 +37,7 @@ fun <T : MediaGroupPartContent> SendMediaGroup(
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null
|
||||
): Request<PossiblySentViaBotCommonMessage<T>> {
|
||||
): Request<PossiblySentViaBotCommonMessage<MediaGroupContent<T>>> {
|
||||
if (media.size !in mediaCountInMediaGroup) {
|
||||
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ fun <T : MediaGroupPartContent> SendMediaGroup(
|
||||
data,
|
||||
SendMediaGroupFiles(files)
|
||||
)
|
||||
}) as Request<PossiblySentViaBotCommonMessage<T>>
|
||||
}) as Request<PossiblySentViaBotCommonMessage<MediaGroupContent<T>>>
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@ fun SendPhoto(
|
||||
photo: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
@@ -36,6 +37,7 @@ fun SendPhoto(
|
||||
text,
|
||||
parseMode,
|
||||
null,
|
||||
spoilered,
|
||||
threadId,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
@@ -55,6 +57,7 @@ fun SendPhoto(
|
||||
chatId: ChatIdentifier,
|
||||
photo: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
@@ -68,6 +71,7 @@ fun SendPhoto(
|
||||
entities.makeString(),
|
||||
null,
|
||||
entities.toRawMessageEntities(),
|
||||
spoilered,
|
||||
threadId,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
@@ -98,6 +102,8 @@ data class SendPhotoData internal constructor(
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
@SerialName(messageThreadIdField)
|
||||
override val threadId: MessageThreadId? = chatId.threadId,
|
||||
@SerialName(disableNotificationField)
|
||||
@@ -113,7 +119,8 @@ data class SendPhotoData internal constructor(
|
||||
) : DataRequest<ContentMessage<PhotoContent>>,
|
||||
SendMessageRequest<ContentMessage<PhotoContent>>,
|
||||
ReplyingMarkupSendMessageRequest<ContentMessage<PhotoContent>>,
|
||||
TextableSendMessageRequest<ContentMessage<PhotoContent>>
|
||||
TextableSendMessageRequest<ContentMessage<PhotoContent>>,
|
||||
OptionallyWithSpoilerRequest
|
||||
{
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
|
||||
@@ -25,6 +25,7 @@ fun SendVideo(
|
||||
thumb: InputFile? = null,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -48,6 +49,7 @@ fun SendVideo(
|
||||
text,
|
||||
parseMode,
|
||||
null,
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -75,6 +77,7 @@ fun SendVideo(
|
||||
video: InputFile,
|
||||
thumb: InputFile? = null,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
duration: Long? = null,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
@@ -98,6 +101,7 @@ fun SendVideo(
|
||||
entities.makeString(),
|
||||
null,
|
||||
entities.toRawMessageEntities(),
|
||||
spoilered,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -137,6 +141,8 @@ data class SendVideoData internal constructor(
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
@SerialName(durationField)
|
||||
override val duration: Long? = null,
|
||||
@SerialName(widthField)
|
||||
@@ -163,7 +169,8 @@ data class SendVideoData internal constructor(
|
||||
TextableSendMessageRequest<ContentMessage<VideoContent>>,
|
||||
ThumbedSendMessageRequest<ContentMessage<VideoContent>>,
|
||||
DuratedSendMessageRequest<ContentMessage<VideoContent>>,
|
||||
SizedSendMessageRequest<ContentMessage<VideoContent>>
|
||||
SizedSendMessageRequest<ContentMessage<VideoContent>>,
|
||||
OptionallyWithSpoilerRequest
|
||||
{
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
|
||||
@@ -54,6 +54,13 @@ value class ChatIdWithThreadId(val chatIdWithThreadId: Pair<Identifier, MessageT
|
||||
val ChatIdentifier.threadId: MessageThreadId?
|
||||
get() = (this as? IdChatIdentifier) ?.threadId
|
||||
|
||||
fun IdChatIdentifier.toChatId() = when (this) {
|
||||
is ChatId -> this
|
||||
is ChatIdWithThreadId -> ChatId(chatId)
|
||||
}
|
||||
|
||||
fun IdChatIdentifier.toChatWithThreadId(threadId: MessageThreadId) = IdChatIdentifier(chatId, threadId)
|
||||
|
||||
/**
|
||||
* https://core.telegram.org/bots/api#formatting-options
|
||||
*/
|
||||
|
||||
@@ -228,6 +228,7 @@ const val allowsMultipleAnswersField = "allows_multiple_answers"
|
||||
const val isAnonymousField = "is_anonymous"
|
||||
const val canManageTopicsField = "can_manage_topics"
|
||||
const val captionEntitiesField = "caption_entities"
|
||||
const val hasSpoilerField = "has_spoiler"
|
||||
const val loginUrlField = "login_url"
|
||||
const val forwardTextField = "forward_text"
|
||||
const val botUsernameField = "bot_username"
|
||||
@@ -242,8 +243,10 @@ const val customTitleField = "custom_title"
|
||||
const val optionIdsField = "option_ids"
|
||||
const val ipAddressField = "ip_address"
|
||||
const val linkedChatIdField = "linked_chat_id"
|
||||
const val hasHiddenMembersField = "has_hidden_members"
|
||||
const val joinToSendMessagesField = "join_to_send_messages"
|
||||
const val joinByRequestField = "join_by_request"
|
||||
const val hasAggressiveAntiSpamEnabledField = "has_aggressive_anti_spam_enabled"
|
||||
const val horizontalAccuracyField = "horizontal_accuracy"
|
||||
const val revokeMessagesField = "revoke_messages"
|
||||
const val messageAutoDeleteTimeField = "message_auto_delete_time"
|
||||
@@ -258,6 +261,19 @@ const val iconColorField = "icon_color"
|
||||
const val requestContactField = "request_contact"
|
||||
const val requestLocationField = "request_location"
|
||||
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 mimeTypeField = "mime_type"
|
||||
@@ -324,7 +340,12 @@ const val scopeField = "scope"
|
||||
const val isMemberField = "is_member"
|
||||
const val isForumField = "is_forum"
|
||||
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 canSendPollsField = "can_send_polls"
|
||||
const val canAddWebPagePreviewsField = "can_add_web_page_previews"
|
||||
@@ -342,6 +363,7 @@ const val canPinMessagesField = "can_pin_messages"
|
||||
const val canPromoteMembersField = "can_promote_members"
|
||||
const val canManageVoiceChatsField = "can_manage_voice_chats"
|
||||
const val canManageVideoChatsField = "can_manage_video_chats"
|
||||
const val useIndependentChatPermissionsField = "use_independent_chat_permissions"
|
||||
const val rightsField = "rights"
|
||||
const val forChannelsField = "for_channels"
|
||||
const val canManageChatField = "can_manage_chat"
|
||||
@@ -372,6 +394,7 @@ const val latitudeField = "latitude"
|
||||
const val longitudeField = "longitude"
|
||||
const val headingField = "heading"
|
||||
const val fromField = "from"
|
||||
const val userChatIdField = "user_chat_id"
|
||||
const val userField = "user"
|
||||
const val dateField = "date"
|
||||
const val chatField = "chat"
|
||||
@@ -461,6 +484,7 @@ const val shouldSendEmailToProviderField = "send_email_to_provider"
|
||||
const val resizeKeyboardField = "resize_keyboard"
|
||||
const val oneTimeKeyboardField = "one_time_keyboard"
|
||||
const val inputFieldPlaceholderField = "input_field_placeholder"
|
||||
const val isPersistentField = "is_persistent"
|
||||
|
||||
const val priceDependOnShipAddressField = "is_flexible"
|
||||
|
||||
|
||||
@@ -94,6 +94,42 @@ data class RequestPollKeyboardButton(
|
||||
val requestPoll: KeyboardButtonPollType
|
||||
) : 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
|
||||
object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
||||
private val internalSerializer = JsonElement.serializer()
|
||||
@@ -124,6 +160,20 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
||||
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(
|
||||
when (asJson) {
|
||||
is JsonObject -> asJson[textField]!!.jsonPrimitive.content
|
||||
@@ -142,6 +192,8 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
||||
is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value)
|
||||
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,9 @@ data class ReplyKeyboardMarkup(
|
||||
val oneTimeKeyboard: Boolean? = null,
|
||||
@SerialName(inputFieldPlaceholderField)
|
||||
val inputFieldPlaceholder: String? = null,
|
||||
val selective: Boolean? = null
|
||||
val selective: Boolean? = null,
|
||||
@SerialName(isPersistentField)
|
||||
val persistent: Boolean? = null
|
||||
) : KeyboardMarkup {
|
||||
init {
|
||||
if (inputFieldPlaceholder != null && inputFieldPlaceholder.length !in inputFieldPlaceholderLimit) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package dev.inmo.tgbotapi.types.buttons.reply
|
||||
|
||||
import dev.inmo.tgbotapi.types.buttons.*
|
||||
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
|
||||
|
||||
|
||||
@@ -67,3 +69,161 @@ inline fun webAppReplyButton(
|
||||
text: String,
|
||||
url: String
|
||||
) = 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,
|
||||
@SerialName(fromField)
|
||||
override val from: User,
|
||||
@SerialName(userChatIdField)
|
||||
val userChatId: UserId,
|
||||
@SerialName(dateField)
|
||||
val date: TelegramDate,
|
||||
@SerialName(inviteLinkField)
|
||||
|
||||
@@ -1,32 +1,259 @@
|
||||
package dev.inmo.tgbotapi.types.chat
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
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(
|
||||
@SerialName(canSendMessagesField)
|
||||
val canSendMessages: Boolean = false,
|
||||
@SerialName(canSendMediaMessagesField)
|
||||
val canSendMediaMessages: Boolean = false,
|
||||
@SerialName(canSendPollsField)
|
||||
val canSendPolls: Boolean = false,
|
||||
@SerialName(canSendOtherMessagesField)
|
||||
val canSendOtherMessages: Boolean = false,
|
||||
@SerialName(canAddWebPagePreviewsField)
|
||||
val canAddWebPagePreviews: Boolean = false,
|
||||
@SerialName(canChangeInfoField)
|
||||
val canChangeInfo: Boolean = false,
|
||||
@SerialName(canInviteUsersField)
|
||||
val canInviteUsers: Boolean = false,
|
||||
@SerialName(canPinMessagesField)
|
||||
val canPinMessages: Boolean = false
|
||||
)
|
||||
/**
|
||||
* Represents any type with common permissions list
|
||||
*
|
||||
* !!WARNING!! Default serializer of this interface is using [Granular] as surrogate and in fact serialized
|
||||
* and deserialized as [Granular]. In case you wish some custom behaviour you must implement your own
|
||||
* [KSerializer] or pass another serializer
|
||||
*/
|
||||
@Serializable(ChatPermissions.Companion::class)
|
||||
interface ChatPermissions {
|
||||
val canSendMessages: Boolean?
|
||||
val canSendAudios: Boolean?
|
||||
val canSendDocuments: Boolean?
|
||||
val canSendPhotos: Boolean?
|
||||
val canSendVideos: Boolean?
|
||||
val canSendVideoNotes: Boolean?
|
||||
val canSendVoiceNotes: Boolean?
|
||||
val canSendPolls: Boolean?
|
||||
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(
|
||||
canSendMessages = true,
|
||||
canSendMediaMessages = true,
|
||||
canSendAudios = true,
|
||||
canSendDocuments = true,
|
||||
canSendPhotos = true,
|
||||
canSendVideos = true,
|
||||
canSendVideoNotes = true,
|
||||
canSendVoiceNotes = true,
|
||||
canSendPolls = true,
|
||||
canSendOtherMessages = true,
|
||||
canAddWebPagePreviews = true,
|
||||
@@ -37,7 +264,12 @@ val LeftRestrictionsChatPermissions = ChatPermissions(
|
||||
|
||||
val RestrictionsChatPermissions = ChatPermissions(
|
||||
canSendMessages = false,
|
||||
canSendMediaMessages = false,
|
||||
canSendAudios = false,
|
||||
canSendDocuments = false,
|
||||
canSendPhotos = false,
|
||||
canSendVideos = false,
|
||||
canSendVideoNotes = false,
|
||||
canSendVoiceNotes = false,
|
||||
canSendPolls = false,
|
||||
canSendOtherMessages = false,
|
||||
canAddWebPagePreviews = false,
|
||||
|
||||
@@ -27,7 +27,9 @@ data class ExtendedChannelChatImpl(
|
||||
@Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class)
|
||||
override val pinnedMessage: Message? = null,
|
||||
@SerialName(linkedChatIdField)
|
||||
override val linkedGroupChatId: IdChatIdentifier? = null
|
||||
override val linkedGroupChatId: IdChatIdentifier? = null,
|
||||
@SerialName(hasHiddenMembersField)
|
||||
override val membersHidden: Boolean = false
|
||||
) : ExtendedChannelChat
|
||||
|
||||
@Serializable
|
||||
@@ -46,7 +48,9 @@ data class ExtendedGroupChatImpl(
|
||||
override val inviteLink: String? = null,
|
||||
@SerialName(pinnedMessageField)
|
||||
@Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class)
|
||||
override val pinnedMessage: Message? = null
|
||||
override val pinnedMessage: Message? = null,
|
||||
@SerialName(hasHiddenMembersField)
|
||||
override val membersHidden: Boolean = false
|
||||
) : ExtendedGroupChat
|
||||
|
||||
@Serializable
|
||||
@@ -109,7 +113,11 @@ data class ExtendedSupergroupChatImpl(
|
||||
@SerialName(joinToSendMessagesField)
|
||||
override val requiresJoinForMessaging: Boolean = false,
|
||||
@SerialName(joinByRequestField)
|
||||
override val requireAdminApproveToJoin: Boolean = false
|
||||
override val requireAdminApproveToJoin: Boolean = false,
|
||||
@SerialName(hasAggressiveAntiSpamEnabledField)
|
||||
override val isAggressiveAntiSpamEnabled: Boolean = false,
|
||||
@SerialName(hasHiddenMembersField)
|
||||
override val membersHidden: Boolean = false
|
||||
) : ExtendedSupergroupChat
|
||||
|
||||
@Serializable
|
||||
@@ -146,7 +154,11 @@ data class ExtendedForumChatImpl(
|
||||
@SerialName(joinToSendMessagesField)
|
||||
override val requiresJoinForMessaging: Boolean = false,
|
||||
@SerialName(joinByRequestField)
|
||||
override val requireAdminApproveToJoin: Boolean = false
|
||||
override val requireAdminApproveToJoin: Boolean = false,
|
||||
@SerialName(hasAggressiveAntiSpamEnabledField)
|
||||
override val isAggressiveAntiSpamEnabled: Boolean = false,
|
||||
@SerialName(hasHiddenMembersField)
|
||||
override val membersHidden: Boolean = false
|
||||
) : ExtendedForumChat
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -31,6 +31,7 @@ sealed interface ExtendedPublicChat : ExtendedChat, PublicChat {
|
||||
val inviteLink: String?
|
||||
@Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class)
|
||||
val pinnedMessage: Message?
|
||||
val membersHidden: Boolean
|
||||
}
|
||||
|
||||
@Serializable(ExtendedChatSerializer::class)
|
||||
@@ -50,6 +51,11 @@ sealed interface ExtendedSupergroupChat : SupergroupChat, ExtendedGroupChat, Ext
|
||||
* This field represents field "join_by_request" from API
|
||||
*/
|
||||
val requireAdminApproveToJoin: Boolean
|
||||
|
||||
/**
|
||||
* This field represents field "has_aggressive_anti_spam_enabled" from API
|
||||
*/
|
||||
val isAggressiveAntiSpamEnabled: Boolean
|
||||
}
|
||||
|
||||
@Serializable(ExtendedChatSerializer::class)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.chat.member
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.chat.ChatPermissions
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@@ -13,15 +14,25 @@ data class RestrictedChatMember(
|
||||
@SerialName(isMemberField)
|
||||
val isMember: Boolean = false,
|
||||
@SerialName(canSendMessagesField)
|
||||
val canSendMessages: Boolean = false,
|
||||
@SerialName(canSendMediaMessagesField)
|
||||
val canSendMediaMessages: Boolean = false,
|
||||
override val canSendMessages: Boolean = false,
|
||||
@SerialName(canSendAudiosField)
|
||||
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)
|
||||
val canSendPolls: Boolean = false,
|
||||
override val canSendPolls: Boolean = false,
|
||||
@SerialName(canSendOtherMessagesField)
|
||||
val canSendOtherMessages: Boolean = false,
|
||||
override val canSendOtherMessages: Boolean = false,
|
||||
@SerialName(canAddWebPagePreviewsField)
|
||||
val canAddWebpagePreviews: Boolean = false,
|
||||
override val canAddWebPagePreviews: Boolean = false,
|
||||
@SerialName(canChangeInfoField)
|
||||
override val canChangeInfo: Boolean = false,
|
||||
@SerialName(canInviteUsersField)
|
||||
@@ -30,7 +41,7 @@ data class RestrictedChatMember(
|
||||
override val canPinMessages: Boolean = false,
|
||||
@SerialName(canManageTopicsField)
|
||||
override val canManageTopics: Boolean = false
|
||||
) : BannedChatMember, SpecialRightsChatMember {
|
||||
) : BannedChatMember, SpecialRightsChatMember, ChatPermissions {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "restricted"
|
||||
|
||||
@@ -34,11 +34,13 @@ data class VideoFile(
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun VideoFile.toTelegramMediaVideo(
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false
|
||||
) = TelegramMediaVideo(
|
||||
fileId,
|
||||
text,
|
||||
parseMode,
|
||||
spoilered,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
@@ -47,10 +49,12 @@ inline fun VideoFile.toTelegramMediaVideo(
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun VideoFile.toTelegramMediaVideo(
|
||||
textSources: TextSourcesList
|
||||
textSources: TextSourcesList,
|
||||
spoilered: Boolean = false
|
||||
) = TelegramMediaVideo(
|
||||
fileId,
|
||||
textSources,
|
||||
spoilered,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
|
||||
@@ -20,4 +20,4 @@ sealed interface AudioMediaGroupMemberTelegramMedia: MediaGroupMemberTelegramMed
|
||||
sealed interface DocumentMediaGroupMemberTelegramMedia: MediaGroupMemberTelegramMedia
|
||||
|
||||
@Serializable(MediaGroupMemberTelegramMediaSerializer::class)
|
||||
sealed interface VisualMediaGroupMemberTelegramMedia : MediaGroupMemberTelegramMedia
|
||||
sealed interface VisualMediaGroupMemberTelegramMedia : MediaGroupMemberTelegramMedia, SpoilerableTelegramMedia
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.media
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.SpoilerableData
|
||||
|
||||
sealed interface SpoilerableTelegramMedia : TelegramMedia, SpoilerableData
|
||||
@@ -18,15 +18,17 @@ fun TelegramMediaAnimation(
|
||||
file: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
duration: Long? = null,
|
||||
thumb: InputFile? = null
|
||||
) = TelegramMediaAnimation(file, text, parseMode, null, width, height, duration, thumb)
|
||||
) = TelegramMediaAnimation(file, text, parseMode, null, spoilered, width, height, duration, thumb)
|
||||
|
||||
fun TelegramMediaAnimation(
|
||||
file: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
duration: Long? = null,
|
||||
@@ -36,6 +38,7 @@ fun TelegramMediaAnimation(
|
||||
entities.makeString(),
|
||||
null,
|
||||
entities.toRawMessageEntities(),
|
||||
spoilered,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
@@ -51,11 +54,13 @@ data class TelegramMediaAnimation internal constructor(
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
override val width: Int? = null,
|
||||
override val height: Int? = null,
|
||||
override val duration: Long? = null,
|
||||
override val thumb: InputFile? = null
|
||||
) : TelegramMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, TextedOutput {
|
||||
) : TelegramMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, TextedOutput, SpoilerableTelegramMedia {
|
||||
override val type: String = "animation"
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
|
||||
@@ -18,13 +18,15 @@ internal const val photoTelegramMediaType = "photo"
|
||||
fun TelegramMediaPhoto(
|
||||
file: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null
|
||||
) = TelegramMediaPhoto(file, text, parseMode, null)
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false
|
||||
) = TelegramMediaPhoto(file, text, parseMode, null, spoilered)
|
||||
|
||||
fun TelegramMediaPhoto(
|
||||
file: InputFile,
|
||||
entities: TextSourcesList
|
||||
) = TelegramMediaPhoto(file, entities.makeString(), null, entities.toRawMessageEntities())
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false
|
||||
) = TelegramMediaPhoto(file, entities.makeString(), null, entities.toRawMessageEntities(), spoilered)
|
||||
|
||||
@Serializable
|
||||
data class TelegramMediaPhoto internal constructor(
|
||||
@@ -34,7 +36,9 @@ data class TelegramMediaPhoto internal constructor(
|
||||
@SerialName(parseModeField)
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
) : TelegramMedia, VisualMediaGroupMemberTelegramMedia {
|
||||
override val type: String = photoTelegramMediaType
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
@@ -50,16 +54,20 @@ data class TelegramMediaPhoto internal constructor(
|
||||
|
||||
fun PhotoSize.toTelegramMediaPhoto(
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false
|
||||
): TelegramMediaPhoto = TelegramMediaPhoto(
|
||||
fileId,
|
||||
text,
|
||||
parseMode
|
||||
parseMode,
|
||||
spoilered
|
||||
)
|
||||
|
||||
fun PhotoSize.toTelegramMediaPhoto(
|
||||
textSources: TextSourcesList = emptyList()
|
||||
textSources: TextSourcesList = emptyList(),
|
||||
spoilered: Boolean = false
|
||||
): TelegramMediaPhoto = TelegramMediaPhoto(
|
||||
fileId,
|
||||
textSources
|
||||
textSources,
|
||||
spoilered
|
||||
)
|
||||
|
||||
@@ -18,20 +18,22 @@ fun TelegramMediaVideo(
|
||||
file: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
duration: Long? = null,
|
||||
thumb: InputFile? = null
|
||||
) = TelegramMediaVideo(file, text, parseMode, null, width, height, duration, thumb)
|
||||
) = TelegramMediaVideo(file, text, parseMode, null, spoilered, width, height, duration, thumb)
|
||||
|
||||
fun TelegramMediaVideo(
|
||||
file: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
width: Int? = null,
|
||||
height: Int? = null,
|
||||
duration: Long? = null,
|
||||
thumb: InputFile? = null
|
||||
) = TelegramMediaVideo(file, entities.makeString(), null, entities.toRawMessageEntities(), width, height, duration, thumb)
|
||||
) = TelegramMediaVideo(file, entities.makeString(), null, entities.toRawMessageEntities(), spoilered, width, height, duration, thumb)
|
||||
|
||||
@Serializable
|
||||
data class TelegramMediaVideo internal constructor (
|
||||
@@ -42,6 +44,8 @@ data class TelegramMediaVideo internal constructor (
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
override val width: Int? = null,
|
||||
override val height: Int? = null,
|
||||
override val duration: Long? = null,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
||||
|
||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
||||
import dev.inmo.tgbotapi.types.iconColorField
|
||||
import dev.inmo.tgbotapi.types.iconCustomEmojiIdField
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
||||
import dev.inmo.tgbotapi.types.nameField
|
||||
import dev.inmo.tgbotapi.utils.RGBColor
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ForumTopicEdited(
|
||||
@SerialName(nameField)
|
||||
val name: String,
|
||||
@SerialName(iconCustomEmojiIdField)
|
||||
val iconEmojiId: CustomEmojiId? = null
|
||||
) : ForumEvent
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
object GeneralForumTopicHidden : ForumEvent
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
object GeneralForumTopicUnhidden : ForumEvent
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
object WriteAccessAllowed : ForumEvent
|
||||
@@ -14,7 +14,11 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||
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.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.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.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
@@ -25,6 +29,8 @@ import dev.inmo.tgbotapi.types.passport.PassportData
|
||||
import dev.inmo.tgbotapi.types.payments.Invoice
|
||||
import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
|
||||
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 kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -58,6 +64,7 @@ internal data class RawMessage(
|
||||
private val entities: RawMessageEntities? = null,
|
||||
private val caption: String? = null,
|
||||
private val caption_entities: RawMessageEntities? = null,
|
||||
private val has_media_spoiler: Boolean? = null,
|
||||
private val audio: AudioFile? = null,
|
||||
private val document: DocumentFile? = null,
|
||||
private val animation: AnimationFile? = null,
|
||||
@@ -88,6 +95,9 @@ internal data class RawMessage(
|
||||
private val dice: Dice? = null,
|
||||
private val successful_payment: SuccessfulPayment? = null,
|
||||
|
||||
private val user_shared: UserShared? = null,
|
||||
private val chat_shared: ChatShared? = null,
|
||||
|
||||
// Voice Chat Service Messages
|
||||
private val video_chat_scheduled: VideoChatScheduled? = null,
|
||||
private val video_chat_started: VideoChatStarted? = null,
|
||||
@@ -96,8 +106,12 @@ internal data class RawMessage(
|
||||
|
||||
// Forum
|
||||
private val forum_topic_created: ForumTopicCreated? = null,
|
||||
private val forum_topic_edited: ForumTopicEdited? = null,
|
||||
private val forum_topic_closed: ForumTopicClosed? = null,
|
||||
private val forum_topic_reopened: ForumTopicReopened? = null,
|
||||
private val general_forum_topic_hidden: GeneralForumTopicHidden? = null,
|
||||
private val general_forum_topic_unhidden: GeneralForumTopicUnhidden? = null,
|
||||
private val write_access_allowed: WriteAccessAllowed? = null,
|
||||
|
||||
// AutoDelete Message time changed
|
||||
private val message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? = null,
|
||||
@@ -129,13 +143,15 @@ internal data class RawMessage(
|
||||
video != null -> VideoContent(
|
||||
video,
|
||||
caption,
|
||||
adaptedCaptionEntities
|
||||
adaptedCaptionEntities,
|
||||
has_media_spoiler ?: false
|
||||
)
|
||||
animation != null -> AnimationContent(
|
||||
animation,
|
||||
document,
|
||||
caption,
|
||||
adaptedCaptionEntities
|
||||
adaptedCaptionEntities,
|
||||
has_media_spoiler ?: false
|
||||
)
|
||||
document != null -> DocumentContent(
|
||||
document,
|
||||
@@ -150,7 +166,8 @@ internal data class RawMessage(
|
||||
photo != null -> PhotoContent(
|
||||
photo.toList(),
|
||||
caption,
|
||||
adaptedCaptionEntities
|
||||
adaptedCaptionEntities,
|
||||
has_media_spoiler ?: false
|
||||
)
|
||||
sticker != null -> StickerContent(sticker)
|
||||
dice != null -> DiceContent(dice)
|
||||
@@ -213,6 +230,10 @@ internal data class RawMessage(
|
||||
video_chat_scheduled != null -> video_chat_scheduled
|
||||
message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed
|
||||
forum_topic_created != null -> forum_topic_created
|
||||
forum_topic_edited != null -> forum_topic_edited
|
||||
general_forum_topic_hidden != null -> general_forum_topic_hidden
|
||||
general_forum_topic_unhidden != null -> general_forum_topic_unhidden
|
||||
write_access_allowed != null -> write_access_allowed
|
||||
forum_topic_closed != null -> forum_topic_closed
|
||||
forum_topic_reopened != null -> forum_topic_reopened
|
||||
video_chat_ended != null -> video_chat_ended
|
||||
@@ -233,6 +254,8 @@ internal data class RawMessage(
|
||||
successful_payment != null -> SuccessfulPaymentEvent(successful_payment)
|
||||
connected_website != null -> UserLoggedIn(connected_website)
|
||||
web_app_data != null -> web_app_data
|
||||
user_shared != null -> user_shared
|
||||
chat_shared != null -> chat_shared
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.inmo.tgbotapi.types.message.content
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.SpoilerableData
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
@@ -23,6 +24,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
mediaGroupPartContentAdditionalBuilder: PolymorphicModuleBuilder<MediaGroupPartContent>.() -> Unit = {},
|
||||
textedMediaContentAdditionalBuilder: PolymorphicModuleBuilder<TextedMediaContent>.() -> Unit = {},
|
||||
mediaContentAdditionalBuilder: PolymorphicModuleBuilder<MediaContent>.() -> Unit = {},
|
||||
spoilerableMediaContentAdditionalBuilder: PolymorphicModuleBuilder<SpoilerableMediaContent>.() -> Unit = {},
|
||||
mediaCollectionContentAdditionalBuilder: PolymorphicModuleBuilder<MediaCollectionContent<*>>.() -> Unit = {},
|
||||
additionalBuilder: PolymorphicModuleBuilder<MessageContent>.() -> Unit = {}
|
||||
) = SerializersModule {
|
||||
@@ -66,6 +68,13 @@ sealed interface MessageContent: ResendableContent {
|
||||
|
||||
mediaContentAdditionalBuilder()
|
||||
}
|
||||
polymorphic(SpoilerableMediaContent::class) {
|
||||
subclass(VideoContent::class)
|
||||
subclass(PhotoContent::class)
|
||||
subclass(AnimationContent::class)
|
||||
|
||||
spoilerableMediaContentAdditionalBuilder()
|
||||
}
|
||||
polymorphic(TextedMediaContent::class) {
|
||||
subclass(PhotoContent::class)
|
||||
subclass(VoiceContent::class)
|
||||
@@ -111,6 +120,8 @@ sealed interface MediaContent: MessageContent {
|
||||
fun asTelegramMedia(): TelegramMedia
|
||||
}
|
||||
|
||||
sealed interface SpoilerableMediaContent : MediaContent, SpoilerableData
|
||||
|
||||
@ClassCastsIncluded
|
||||
sealed interface ResendableContent {
|
||||
fun createResend(
|
||||
|
||||
@@ -39,6 +39,6 @@ sealed interface MediaGroupPartContent : TextedMediaContent {
|
||||
fun toMediaGroupMemberTelegramMedia(): MediaGroupMemberTelegramMedia
|
||||
}
|
||||
|
||||
sealed interface VisualMediaGroupPartContent : MediaGroupPartContent {
|
||||
sealed interface VisualMediaGroupPartContent : MediaGroupPartContent, SpoilerableMediaContent {
|
||||
override fun toMediaGroupMemberTelegramMedia(): VisualMediaGroupMemberTelegramMedia
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ data class AnimationContent(
|
||||
override val media: AnimationFile,
|
||||
val includedDocument: DocumentFile?,
|
||||
override val text: String?,
|
||||
override val textSources: TextSourcesList = emptyList()
|
||||
) : TextedMediaContent {
|
||||
override val textSources: TextSourcesList = emptyList(),
|
||||
override val spoilered: Boolean = false
|
||||
) : TextedMediaContent, SpoilerableMediaContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
messageThreadId: MessageThreadId?,
|
||||
@@ -33,6 +34,7 @@ data class AnimationContent(
|
||||
media.fileId,
|
||||
media.thumb ?.fileId,
|
||||
textSources,
|
||||
spoilered,
|
||||
media.duration,
|
||||
media.width,
|
||||
media.height,
|
||||
@@ -47,6 +49,7 @@ data class AnimationContent(
|
||||
override fun asTelegramMedia(): TelegramMediaAnimation = TelegramMediaAnimation(
|
||||
media.fileId,
|
||||
textSources,
|
||||
spoilered,
|
||||
media.width,
|
||||
media.height,
|
||||
media.duration,
|
||||
|
||||
@@ -17,7 +17,8 @@ import kotlinx.serialization.Serializable
|
||||
data class PhotoContent(
|
||||
override val mediaCollection: Photo,
|
||||
override val text: String? = null,
|
||||
override val textSources: TextSourcesList = emptyList()
|
||||
override val textSources: TextSourcesList = emptyList(),
|
||||
override val spoilered: Boolean = false
|
||||
) : MediaCollectionContent<PhotoSize>, VisualMediaGroupPartContent {
|
||||
override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content")
|
||||
|
||||
@@ -33,6 +34,7 @@ data class PhotoContent(
|
||||
chatId,
|
||||
media.fileId,
|
||||
textSources,
|
||||
spoilered,
|
||||
messageThreadId,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
@@ -43,5 +45,5 @@ data class PhotoContent(
|
||||
|
||||
override fun toMediaGroupMemberTelegramMedia(): TelegramMediaPhoto = asTelegramMedia()
|
||||
|
||||
override fun asTelegramMedia(): TelegramMediaPhoto = media.toTelegramMediaPhoto(textSources)
|
||||
override fun asTelegramMedia(): TelegramMediaPhoto = media.toTelegramMediaPhoto(textSources, spoilered)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ import kotlinx.serialization.Serializable
|
||||
data class VideoContent(
|
||||
override val media: VideoFile,
|
||||
override val text: String? = null,
|
||||
override val textSources: TextSourcesList = emptyList()
|
||||
override val textSources: TextSourcesList = emptyList(),
|
||||
override val spoilered: Boolean = false
|
||||
) : VisualMediaGroupPartContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
@@ -32,6 +33,7 @@ data class VideoContent(
|
||||
media.fileId,
|
||||
media.thumb ?.fileId,
|
||||
textSources,
|
||||
spoilered,
|
||||
media.duration,
|
||||
media.width,
|
||||
media.height,
|
||||
|
||||
@@ -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.WebAppInlineKeyboardButton
|
||||
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.ReplyForce
|
||||
import dev.inmo.tgbotapi.types.buttons.ReplyKeyboardMarkup
|
||||
@@ -213,6 +214,7 @@ import dev.inmo.tgbotapi.types.media.DocumentMediaGroupMemberTelegramMedia
|
||||
import dev.inmo.tgbotapi.types.media.DuratedTelegramMedia
|
||||
import dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramMedia
|
||||
import dev.inmo.tgbotapi.types.media.SizedTelegramMedia
|
||||
import dev.inmo.tgbotapi.types.media.SpoilerableTelegramMedia
|
||||
import dev.inmo.tgbotapi.types.media.TelegramMedia
|
||||
import dev.inmo.tgbotapi.types.media.TelegramMediaAnimation
|
||||
import dev.inmo.tgbotapi.types.media.TelegramMediaAudio
|
||||
@@ -251,7 +253,11 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent
|
||||
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.ForumTopicEdited
|
||||
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.VideoChatEnded
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatParticipantsInvited
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatScheduled
|
||||
@@ -315,6 +321,7 @@ import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
import dev.inmo.tgbotapi.types.message.content.PhotoContent
|
||||
import dev.inmo.tgbotapi.types.message.content.PollContent
|
||||
import dev.inmo.tgbotapi.types.message.content.ResendableContent
|
||||
import dev.inmo.tgbotapi.types.message.content.SpoilerableMediaContent
|
||||
import dev.inmo.tgbotapi.types.message.content.StaticLocationContent
|
||||
import dev.inmo.tgbotapi.types.message.content.StickerContent
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
@@ -427,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.MessageGameShortNameCallbackQuery
|
||||
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.ChannelPostUpdate
|
||||
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
|
||||
@@ -1873,6 +1884,34 @@ public inline fun <T>
|
||||
InlineKeyboardButton.ifWebAppInlineKeyboardButton(block: (WebAppInlineKeyboardButton) -> T): T?
|
||||
= 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?
|
||||
dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||
|
||||
@@ -2643,6 +2682,16 @@ public inline fun TelegramMedia.sizedTelegramMediaOrThrow(): SizedTelegramMedia
|
||||
public inline fun <T> TelegramMedia.ifSizedTelegramMedia(block: (SizedTelegramMedia) -> T): T? =
|
||||
sizedTelegramMediaOrNull() ?.let(block)
|
||||
|
||||
public inline fun TelegramMedia.spoilerableTelegramMediaOrNull(): SpoilerableTelegramMedia? = this
|
||||
as? dev.inmo.tgbotapi.types.media.SpoilerableTelegramMedia
|
||||
|
||||
public inline fun TelegramMedia.spoilerableTelegramMediaOrThrow(): SpoilerableTelegramMedia = this
|
||||
as dev.inmo.tgbotapi.types.media.SpoilerableTelegramMedia
|
||||
|
||||
public inline fun <T>
|
||||
TelegramMedia.ifSpoilerableTelegramMedia(block: (SpoilerableTelegramMedia) -> T): T? =
|
||||
spoilerableTelegramMediaOrNull() ?.let(block)
|
||||
|
||||
public inline fun TelegramMedia.telegramMediaAnimationOrNull(): TelegramMediaAnimation? = this as?
|
||||
dev.inmo.tgbotapi.types.media.TelegramMediaAnimation
|
||||
|
||||
@@ -2923,6 +2972,15 @@ public inline fun ChatEvent.forumTopicCreatedOrThrow(): ForumTopicCreated = this
|
||||
public inline fun <T> ChatEvent.ifForumTopicCreated(block: (ForumTopicCreated) -> T): T? =
|
||||
forumTopicCreatedOrNull() ?.let(block)
|
||||
|
||||
public inline fun ChatEvent.forumTopicEditedOrNull(): ForumTopicEdited? = this as?
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicEdited
|
||||
|
||||
public inline fun ChatEvent.forumTopicEditedOrThrow(): ForumTopicEdited = this as
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicEdited
|
||||
|
||||
public inline fun <T> ChatEvent.ifForumTopicEdited(block: (ForumTopicEdited) -> T): T? =
|
||||
forumTopicEditedOrNull() ?.let(block)
|
||||
|
||||
public inline fun ChatEvent.forumTopicReopenedOrNull(): ForumTopicReopened? = this as?
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicReopened
|
||||
|
||||
@@ -2932,6 +2990,34 @@ public inline fun ChatEvent.forumTopicReopenedOrThrow(): ForumTopicReopened = th
|
||||
public inline fun <T> ChatEvent.ifForumTopicReopened(block: (ForumTopicReopened) -> T): T? =
|
||||
forumTopicReopenedOrNull() ?.let(block)
|
||||
|
||||
public inline fun ChatEvent.generalForumTopicHiddenOrNull(): GeneralForumTopicHidden? = this as?
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.GeneralForumTopicHidden
|
||||
|
||||
public inline fun ChatEvent.generalForumTopicHiddenOrThrow(): GeneralForumTopicHidden = this as
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.GeneralForumTopicHidden
|
||||
|
||||
public inline fun <T> ChatEvent.ifGeneralForumTopicHidden(block: (GeneralForumTopicHidden) -> T): T?
|
||||
= generalForumTopicHiddenOrNull() ?.let(block)
|
||||
|
||||
public inline fun ChatEvent.generalForumTopicUnhiddenOrNull(): GeneralForumTopicUnhidden? = this as?
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.GeneralForumTopicUnhidden
|
||||
|
||||
public inline fun ChatEvent.generalForumTopicUnhiddenOrThrow(): GeneralForumTopicUnhidden = this as
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.GeneralForumTopicUnhidden
|
||||
|
||||
public inline fun <T>
|
||||
ChatEvent.ifGeneralForumTopicUnhidden(block: (GeneralForumTopicUnhidden) -> T): T? =
|
||||
generalForumTopicUnhiddenOrNull() ?.let(block)
|
||||
|
||||
public inline fun ChatEvent.writeAccessAllowedOrNull(): WriteAccessAllowed? = this as?
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.WriteAccessAllowed
|
||||
|
||||
public inline fun ChatEvent.writeAccessAllowedOrThrow(): WriteAccessAllowed = this as
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.forum.WriteAccessAllowed
|
||||
|
||||
public inline fun <T> ChatEvent.ifWriteAccessAllowed(block: (WriteAccessAllowed) -> T): T? =
|
||||
writeAccessAllowedOrNull() ?.let(block)
|
||||
|
||||
public inline fun ChatEvent.videoChatEndedOrNull(): VideoChatEnded? = this as?
|
||||
dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatEnded
|
||||
|
||||
@@ -2978,6 +3064,33 @@ public inline fun ChatEvent.successfulPaymentEventOrThrow(): SuccessfulPaymentEv
|
||||
public inline fun <T> ChatEvent.ifSuccessfulPaymentEvent(block: (SuccessfulPaymentEvent) -> T): T? =
|
||||
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?
|
||||
dev.inmo.tgbotapi.types.message.ForwardInfo.ByAnonymous
|
||||
|
||||
@@ -3516,6 +3629,16 @@ public inline fun ResendableContent.mediaContentOrThrow(): MediaContent = this a
|
||||
public inline fun <T> ResendableContent.ifMediaContent(block: (MediaContent) -> T): T? =
|
||||
mediaContentOrNull() ?.let(block)
|
||||
|
||||
public inline fun ResendableContent.spoilerableMediaContentOrNull(): SpoilerableMediaContent? = this
|
||||
as? dev.inmo.tgbotapi.types.message.content.SpoilerableMediaContent
|
||||
|
||||
public inline fun ResendableContent.spoilerableMediaContentOrThrow(): SpoilerableMediaContent = this
|
||||
as dev.inmo.tgbotapi.types.message.content.SpoilerableMediaContent
|
||||
|
||||
public inline fun <T>
|
||||
ResendableContent.ifSpoilerableMediaContent(block: (SpoilerableMediaContent) -> T): T? =
|
||||
spoilerableMediaContentOrNull() ?.let(block)
|
||||
|
||||
public inline fun ResendableContent.audioMediaGroupPartContentOrNull(): AudioMediaGroupPartContent?
|
||||
= this as? dev.inmo.tgbotapi.types.message.content.AudioMediaGroupPartContent
|
||||
|
||||
@@ -4596,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 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?
|
||||
dev.inmo.tgbotapi.types.update.CallbackQueryUpdate
|
||||
|
||||
|
||||
@@ -7,39 +7,61 @@ import dev.inmo.tgbotapi.types.message.textsources.link
|
||||
import io.ktor.http.encodeURLQueryComponent
|
||||
|
||||
|
||||
fun makeUsernameLink(username: String) = "$internalLinkBeginning/$username"
|
||||
fun makeUsernameLink(username: String, threadId: MessageThreadId? = null) = "$internalLinkBeginning/$username${threadId ?.let { "/$it" } ?: ""}"
|
||||
fun makeChatLink(identifier: Identifier, threadId: MessageThreadId? = null) = identifier.toString().replace(
|
||||
linkIdRedundantPartRegex,
|
||||
""
|
||||
).let { bareId ->
|
||||
"$internalLinkBeginning/c/$bareId${threadId ?.let { "/$it" } ?: ""}"
|
||||
}
|
||||
fun makeUsernameDeepLinkPrefix(username: String) = "${makeUsernameLink(username)}?start="
|
||||
fun makeUsernameStartattachPrefix(username: String) = "$internalLinkBeginning/$username?startattach"
|
||||
fun makeUsernameStartattachLink(username: String, data: String? = null) = "${makeUsernameStartattachPrefix(username)}${data?.let { "=$it" } ?: ""}"
|
||||
inline val Username.link
|
||||
get() = makeUsernameLink(usernameWithoutAt)
|
||||
val IdChatIdentifier.link: String
|
||||
get() = makeChatLink(chatId, threadId)
|
||||
fun ChatId.link(threadId: MessageThreadId?) = makeChatLink(chatId, threadId)
|
||||
inline fun Username.link(threadId: MessageThreadId?) = makeUsernameLink(usernameWithoutAt, threadId)
|
||||
inline val Username.deepLinkPrefix
|
||||
get() = makeUsernameDeepLinkPrefix(usernameWithoutAt)
|
||||
inline val Username.startattachPrefix
|
||||
get() = makeUsernameStartattachPrefix(usernameWithoutAt)
|
||||
inline fun makeLink(username: Username) = username.link
|
||||
inline fun makeLink(username: Username, threadId: MessageThreadId? = null) = username.link(threadId)
|
||||
inline fun makeTelegramDeepLink(username: String, startParameter: String) = "${makeUsernameDeepLinkPrefix(username)}$startParameter".encodeURLQueryComponent()
|
||||
inline fun makeTelegramStartattach(username: String, data: String? = null) = makeUsernameStartattachLink(username, data)
|
||||
inline fun makeDeepLink(username: Username, startParameter: String) = makeTelegramDeepLink(username.usernameWithoutAt, startParameter)
|
||||
inline fun makeTelegramDeepLink(username: Username, startParameter: String) = makeDeepLink(username, startParameter)
|
||||
inline fun makeTelegramStartattach(username: Username, data: String? = null) = makeTelegramStartattach(username.usernameWithoutAt, data)
|
||||
|
||||
fun makeLinkToMessage(
|
||||
username: String,
|
||||
messageId: MessageId
|
||||
): String = "$internalLinkBeginning/$username/$messageId"
|
||||
fun makeLinkToMessage(
|
||||
username: Username,
|
||||
messageId: MessageId
|
||||
): String = makeLinkToMessage(username.username, messageId)
|
||||
fun makeLinkToMessage(
|
||||
chat: UsernameChat,
|
||||
messageId: MessageId
|
||||
): String? = chat.username ?.let { makeLinkToMessage(it, messageId) }
|
||||
|
||||
private val linkIdRedundantPartRegex = Regex("^-100")
|
||||
private val usernameBeginSymbolRegex = Regex("^@")
|
||||
|
||||
fun makeLinkToMessage(
|
||||
username: String,
|
||||
messageId: MessageId,
|
||||
threadId: MessageThreadId? = null
|
||||
): String = "${makeUsernameLink(username, threadId)}/$messageId"
|
||||
fun makeLinkToMessage(
|
||||
username: Username,
|
||||
messageId: MessageId,
|
||||
threadId: MessageThreadId? = null
|
||||
): String = makeLinkToMessage(username.username, messageId, threadId)
|
||||
fun makeLinkToMessage(
|
||||
chatId: Identifier,
|
||||
messageId: MessageId,
|
||||
threadId: MessageThreadId? = null
|
||||
): String = chatId.toString().replace(
|
||||
linkIdRedundantPartRegex,
|
||||
""
|
||||
).let { bareId ->
|
||||
"$internalLinkBeginning/c/$bareId/${threadId ?.let { "$it/" } ?: ""}$messageId"
|
||||
}
|
||||
fun makeLinkToMessage(
|
||||
chatId: IdChatIdentifier,
|
||||
messageId: MessageId,
|
||||
): String = makeLinkToMessage(chatId.chatId, messageId, chatId.threadId)
|
||||
|
||||
/**
|
||||
* Link which can be used as by any user to get access to [Message]. Returns null in case when there are no
|
||||
* known way to build link (for [PrivateChat]s, for example)
|
||||
@@ -49,16 +71,10 @@ fun makeLinkToMessage(
|
||||
messageId: MessageId
|
||||
): String? {
|
||||
return when {
|
||||
chat is UsernameChat && chat.username != null -> {
|
||||
"$internalLinkBeginning/${chat.username ?.username ?.replace(
|
||||
usernameBeginSymbolRegex, "")}/$messageId"
|
||||
}
|
||||
chat !is PrivateChat -> chat.id.chatId.toString().replace(
|
||||
linkIdRedundantPartRegex,
|
||||
""
|
||||
).let { bareId ->
|
||||
"$internalLinkBeginning/c/$bareId/$messageId"
|
||||
}
|
||||
chat is UsernameChat && chat.username != null -> chat.username ?.let {
|
||||
makeLinkToMessage(it, messageId, chat.id.threadId)
|
||||
} ?: makeLinkToMessage(chat.id, messageId)
|
||||
chat !is PrivateChat -> makeLinkToMessage(chat.id, messageId)
|
||||
else -> return null
|
||||
}
|
||||
}
|
||||
@@ -79,7 +95,7 @@ val Message.link: String?
|
||||
val Chat.link: String?
|
||||
get() {
|
||||
if (this is UsernameChat) {
|
||||
username ?.link
|
||||
username ?.link ?: id.link
|
||||
}
|
||||
if (this is ExtendedPublicChat) {
|
||||
inviteLink ?.let { return it }
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.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.utils.*
|
||||
|
||||
@@ -22,7 +26,8 @@ fun ReplyKeyboardBuilder.build(
|
||||
oneTimeKeyboard: Boolean? = null,
|
||||
inputFieldPlaceholder: String? = null,
|
||||
selective: Boolean? = null,
|
||||
) = ReplyKeyboardMarkup(matrix, resizeKeyboard, oneTimeKeyboard, inputFieldPlaceholder, selective)
|
||||
persistent: Boolean? = null,
|
||||
) = ReplyKeyboardMarkup(matrix, resizeKeyboard, oneTimeKeyboard, inputFieldPlaceholder, selective, persistent)
|
||||
|
||||
/**
|
||||
* Row builder of [KeyboardButton]
|
||||
@@ -43,8 +48,9 @@ inline fun replyKeyboard(
|
||||
oneTimeKeyboard: Boolean? = null,
|
||||
inputFieldPlaceholder: String? = null,
|
||||
selective: Boolean? = null,
|
||||
persistent: Boolean? = null,
|
||||
block: ReplyKeyboardBuilder.() -> Unit
|
||||
) = ReplyKeyboardBuilder().apply(block).build(resizeKeyboard, oneTimeKeyboard, inputFieldPlaceholder, selective)
|
||||
) = ReplyKeyboardBuilder().apply(block).build(resizeKeyboard, oneTimeKeyboard, inputFieldPlaceholder, selective, persistent)
|
||||
|
||||
/**
|
||||
* Factory-function for [ReplyKeyboardBuilder], but in difference with [replyKeyboard] this method will create single-row
|
||||
@@ -55,8 +61,9 @@ inline fun flatReplyKeyboard(
|
||||
oneTimeKeyboard: Boolean? = null,
|
||||
inputFieldPlaceholder: String? = null,
|
||||
selective: Boolean? = null,
|
||||
persistent: Boolean? = null,
|
||||
block: ReplyKeyboardRowBuilder.() -> Unit
|
||||
) = replyKeyboard(resizeKeyboard, oneTimeKeyboard, inputFieldPlaceholder, selective) {
|
||||
) = replyKeyboard(resizeKeyboard, oneTimeKeyboard, inputFieldPlaceholder, selective, persistent) {
|
||||
row<KeyboardButton>(block)
|
||||
}
|
||||
|
||||
@@ -135,3 +142,164 @@ inline fun ReplyKeyboardRowBuilder.webAppButton(
|
||||
text: String,
|
||||
url: String
|
||||
) = 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
|
||||
)
|
||||
)
|
||||
|
||||
@@ -9,11 +9,13 @@ fun ReplyKeyboardMarkup(
|
||||
resizeKeyboard: Boolean? = null,
|
||||
oneTimeKeyboard: Boolean? = null,
|
||||
inputFieldPlaceholder: String? = null,
|
||||
selective: Boolean? = null
|
||||
selective: Boolean? = null,
|
||||
persistent: Boolean? = null
|
||||
): ReplyKeyboardMarkup = ReplyKeyboardMarkup(
|
||||
flatMatrix { buttons.forEach { +it } },
|
||||
resizeKeyboard,
|
||||
oneTimeKeyboard,
|
||||
inputFieldPlaceholder,
|
||||
selective
|
||||
selective,
|
||||
persistent
|
||||
)
|
||||
|
||||
@@ -5,8 +5,8 @@ import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.bot.exceptions.*
|
||||
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.webhook.DeleteWebhook
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
|
||||
@@ -23,59 +23,86 @@ fun TelegramBot.longPollingFlow(
|
||||
timeoutSeconds: Seconds = 30,
|
||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true
|
||||
): Flow<Update> = channelFlow {
|
||||
if (autoDisableWebhooks) {
|
||||
runCatchingSafely {
|
||||
execute(DeleteWebhook())
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
while (isActive) {
|
||||
safely(
|
||||
{ e ->
|
||||
exceptionsHandler ?.invoke(e)
|
||||
if (e is RequestException) {
|
||||
delay(1000L)
|
||||
withContext(contextToWork) {
|
||||
while (isActive) {
|
||||
safely(
|
||||
{ e ->
|
||||
val isHttpRequestTimeoutException = e is HttpRequestTimeoutException || (e is CommonBotException && e.cause is HttpRequestTimeoutException)
|
||||
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 {
|
||||
for (update in updates) {
|
||||
send(update)
|
||||
safelyWithResult {
|
||||
for (update in updates) {
|
||||
send(update)
|
||||
|
||||
lastUpdateIdentifier = update.updateId
|
||||
lastUpdateIdentifier = update.updateId
|
||||
}
|
||||
}.onFailure {
|
||||
cancel(it as? CancellationException ?: return@onFailure)
|
||||
}
|
||||
}.onFailure {
|
||||
cancel(it as? CancellationException ?: return@onFailure)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,8 +113,16 @@ fun TelegramBot.startGettingOfUpdatesByLongPolling(
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
updatesReceiver: UpdateReceiver<Update>
|
||||
): Job = longPollingFlow(timeoutSeconds, exceptionsHandler, allowedUpdates).subscribeSafely(
|
||||
): Job = longPollingFlow(
|
||||
timeoutSeconds = timeoutSeconds,
|
||||
exceptionsHandler = exceptionsHandler,
|
||||
allowedUpdates = allowedUpdates,
|
||||
autoDisableWebhooks = autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions
|
||||
).subscribeSafely(
|
||||
scope,
|
||||
exceptionsHandler ?: defaultSafelyExceptionHandler,
|
||||
updatesReceiver
|
||||
@@ -101,7 +136,8 @@ fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
||||
avoidInlineQueries: Boolean = false,
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
autoDisableWebhooks: Boolean = true
|
||||
): Flow<Update> = longPollingFlow(
|
||||
timeoutSeconds = 0,
|
||||
exceptionsHandler = {
|
||||
@@ -111,7 +147,9 @@ fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
||||
else -> exceptionsHandler ?.invoke(it)
|
||||
}
|
||||
},
|
||||
allowedUpdates = allowedUpdates
|
||||
allowedUpdates = allowedUpdates,
|
||||
autoDisableWebhooks = autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions = false
|
||||
).filter {
|
||||
!(it is InlineQueryUpdate && avoidInlineQueries || it is CallbackQueryUpdate && avoidCallbackQueries)
|
||||
}
|
||||
@@ -122,12 +160,14 @@ fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
updatesReceiver: UpdateReceiver<Update>
|
||||
): Job = createAccumulatedUpdatesRetrieverFlow(
|
||||
avoidInlineQueries,
|
||||
avoidCallbackQueries,
|
||||
exceptionsHandler,
|
||||
allowedUpdates
|
||||
allowedUpdates,
|
||||
autoDisableWebhooks
|
||||
).subscribeSafelyWithoutExceptions(
|
||||
scope.LinkedSupervisorScope()
|
||||
) {
|
||||
@@ -139,6 +179,7 @@ fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries: Boolean = false,
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null
|
||||
) = retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries,
|
||||
@@ -146,6 +187,7 @@ fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
scope,
|
||||
exceptionsHandler,
|
||||
flowsUpdatesFilter.allowedUpdates,
|
||||
autoDisableWebhooks,
|
||||
flowsUpdatesFilter.asUpdateReceiver
|
||||
)
|
||||
|
||||
@@ -155,6 +197,7 @@ suspend fun TelegramBot.flushAccumulatedUpdates(
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
updatesReceiver: UpdateReceiver<Update> = {}
|
||||
) = retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries,
|
||||
@@ -162,6 +205,7 @@ suspend fun TelegramBot.flushAccumulatedUpdates(
|
||||
scope,
|
||||
exceptionsHandler,
|
||||
allowedUpdates,
|
||||
autoDisableWebhooks,
|
||||
updatesReceiver
|
||||
).join()
|
||||
|
||||
@@ -173,9 +217,19 @@ fun TelegramBot.longPolling(
|
||||
updatesFilter: UpdatesFilter,
|
||||
timeoutSeconds: Seconds = 30,
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null
|
||||
): Job = updatesFilter.run {
|
||||
startGettingOfUpdatesByLongPolling(timeoutSeconds, scope, exceptionsHandler, allowedUpdates, asUpdateReceiver)
|
||||
startGettingOfUpdatesByLongPolling(
|
||||
timeoutSeconds = timeoutSeconds,
|
||||
scope = scope,
|
||||
exceptionsHandler = exceptionsHandler,
|
||||
allowedUpdates = allowedUpdates,
|
||||
autoDisableWebhooks = autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions,
|
||||
updatesReceiver = asUpdateReceiver
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,18 +243,24 @@ fun TelegramBot.longPolling(
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
flowsUpdatesFilterUpdatesKeeperCount: Int = 100,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
flowUpdatesPreset: FlowsUpdatesFilter.() -> Unit
|
||||
): Job = longPolling(FlowsUpdatesFilter(flowsUpdatesFilterUpdatesKeeperCount).apply(flowUpdatesPreset), timeoutSeconds, scope, exceptionsHandler)
|
||||
): Job = longPolling(FlowsUpdatesFilter(flowsUpdatesFilterUpdatesKeeperCount).apply(flowUpdatesPreset), timeoutSeconds, scope, autoDisableWebhooks, autoSkipTimeoutExceptions, exceptionsHandler)
|
||||
|
||||
fun RequestsExecutor.startGettingOfUpdatesByLongPolling(
|
||||
updatesFilter: UpdatesFilter,
|
||||
timeoutSeconds: Seconds = 30,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
): Job = startGettingOfUpdatesByLongPolling(
|
||||
timeoutSeconds,
|
||||
scope,
|
||||
exceptionsHandler,
|
||||
updatesFilter.allowedUpdates,
|
||||
autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions,
|
||||
updatesFilter.asUpdateReceiver
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.launchSafely
|
||||
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
|
||||
@@ -29,15 +31,18 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
|
||||
)
|
||||
|
||||
launch {
|
||||
launch {
|
||||
launchSafelyWithoutExceptions {
|
||||
for (update in updatesChannel) {
|
||||
when (val data = update.data) {
|
||||
is PossiblyMediaGroupMessage<*> -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate)
|
||||
val data = update.data
|
||||
when {
|
||||
data is PossiblyMediaGroupMessage<*> && data.mediaGroupId != null -> {
|
||||
mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate)
|
||||
}
|
||||
else -> output(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
launch {
|
||||
launchSafelyWithoutExceptions {
|
||||
for ((_, mediaGroup) in mediaGroupAccumulatedChannel) {
|
||||
mediaGroup.convertWithMediaGroupUpdates().forEach {
|
||||
output(it)
|
||||
|
||||
@@ -41,10 +41,9 @@ fun Route.includeWebhookHandlingInRoute(
|
||||
post {
|
||||
try {
|
||||
runCatchingSafely {
|
||||
val asJson = nonstrictJsonFormat.parseToJsonElement(call.receiveText())
|
||||
val update = nonstrictJsonFormat.decodeFromJsonElement(
|
||||
val update = nonstrictJsonFormat.decodeFromString(
|
||||
UpdateDeserializationStrategy,
|
||||
asJson
|
||||
call.receiveText()
|
||||
)
|
||||
transformer(update)
|
||||
}.onSuccess {
|
||||
|
||||
@@ -6,3 +6,5 @@ typealias EventHandler = WebApp.() -> Unit
|
||||
typealias ViewportChangedEventHandler = WebApp.(ViewportChangedData) -> Unit
|
||||
typealias InvoiceClosedEventHandler = WebApp.(InvoiceClosedInfo) -> Unit
|
||||
typealias PopupClosedEventHandler = WebApp.(String?) -> Unit
|
||||
typealias QRTextReceivedEventHandler = WebApp.(String) -> Boolean
|
||||
typealias TextReceivedEventHandler = WebApp.(String) -> Unit
|
||||
|
||||
@@ -8,4 +8,6 @@ sealed class EventType(val typeName: String) {
|
||||
object SettingsButtonClicked : EventType("settingsButtonClicked")
|
||||
object InvoiceClosed : EventType("invoiceClosed")
|
||||
object PopupClosed : EventType("popupClosed")
|
||||
object QRTextReceived : EventType("qrTextReceived")
|
||||
object ClipboardTextReceived : EventType("clipboardTextReceived")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.inmo.tgbotapi.webapps
|
||||
|
||||
import kotlin.js.json
|
||||
|
||||
external interface OpenLinkParams {
|
||||
@JsName("try_instant_view")
|
||||
val tryInstantView: Boolean
|
||||
}
|
||||
|
||||
fun OpenLinkParams(
|
||||
tryInstantView: Boolean
|
||||
) = json(
|
||||
*listOfNotNull(
|
||||
"try_instant_view" to tryInstantView
|
||||
).toTypedArray()
|
||||
).unsafeCast<OpenLinkParams>()
|
||||
@@ -0,0 +1,3 @@
|
||||
package dev.inmo.tgbotapi.webapps
|
||||
|
||||
typealias QRTextReceivedCallback = (String) -> Boolean
|
||||
@@ -0,0 +1,3 @@
|
||||
package dev.inmo.tgbotapi.webapps
|
||||
|
||||
typealias TextReceivedCallback = (String) -> Unit
|
||||
@@ -8,6 +8,8 @@ import dev.inmo.tgbotapi.webapps.popup.*
|
||||
external class WebApp {
|
||||
val version: String
|
||||
|
||||
val platform: String
|
||||
|
||||
val initData: String
|
||||
val initDataUnsafe: WebAppInitData
|
||||
|
||||
@@ -33,6 +35,9 @@ external class WebApp {
|
||||
fun showPopup(params: PopupParams, callback: ClosePopupCallback? = definedExternally)
|
||||
fun showAlert(message: String, callback: AlertCallback? = definedExternally)
|
||||
fun showConfirm(message: String, callback: ConfirmCallback? = definedExternally)
|
||||
fun showScanQrPopup(params: ScanQrPopupParams, callback: QRTextReceivedCallback? = definedExternally)
|
||||
fun closeScanQrPopup()
|
||||
fun readTextFromClipboard(callback: TextReceivedCallback? = definedExternally)
|
||||
|
||||
@JsName("MainButton")
|
||||
val mainButton: MainButton
|
||||
@@ -50,6 +55,10 @@ external class WebApp {
|
||||
internal fun onEventWithInvoiceClosedInfo(type: String, callback: (InvoiceClosedInfo) -> Unit)
|
||||
@JsName("onEvent")
|
||||
internal fun onEventWithPopupClosedInfo(type: String, callback: (String?) -> Unit)
|
||||
@JsName("onEvent")
|
||||
internal fun onEventWithQRTextInfo(type: String, callback: (String) -> Boolean)
|
||||
@JsName("onEvent")
|
||||
internal fun onEventWithTextInfo(type: String, callback: (String) -> Unit)
|
||||
|
||||
fun offEvent(type: String, callback: () -> Unit)
|
||||
@JsName("offEvent")
|
||||
@@ -124,6 +133,30 @@ fun WebApp.onEvent(type: EventType.PopupClosed, eventHandler: PopupClosedEventHa
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The callback which should be used in case you want to turn off events handling
|
||||
*/
|
||||
fun WebApp.onEvent(type: EventType.QRTextReceived, eventHandler: QRTextReceivedEventHandler) = { it: String ->
|
||||
eventHandler(js("this").unsafeCast<WebApp>(), it)
|
||||
}.also {
|
||||
onEventWithQRTextInfo(
|
||||
type.typeName,
|
||||
callback = it
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The callback which should be used in case you want to turn off events handling
|
||||
*/
|
||||
fun WebApp.onEvent(type: EventType.ClipboardTextReceived, eventHandler: TextReceivedEventHandler) = { it: String ->
|
||||
eventHandler(js("this").unsafeCast<WebApp>(), it)
|
||||
}.also {
|
||||
onEventWithTextInfo(
|
||||
type.typeName,
|
||||
callback = it
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The callback which should be used in case you want to turn off events handling
|
||||
*/
|
||||
@@ -152,6 +185,14 @@ fun WebApp.onInvoiceClosed(eventHandler: InvoiceClosedEventHandler) = onEvent(Ev
|
||||
* @return The callback which should be used in case you want to turn off events handling
|
||||
*/
|
||||
fun WebApp.onPopupClosed(eventHandler: PopupClosedEventHandler) = onEvent(EventType.PopupClosed, eventHandler)
|
||||
/**
|
||||
* @return The callback which should be used in case you want to turn off events handling
|
||||
*/
|
||||
fun WebApp.onQRTextReceived(eventHandler: QRTextReceivedEventHandler) = onEvent(EventType.QRTextReceived, eventHandler)
|
||||
/**
|
||||
* @return The callback which should be used in case you want to turn off events handling
|
||||
*/
|
||||
fun WebApp.onClipboardTextReceived(eventHandler: TextReceivedEventHandler) = onEvent(EventType.ClipboardTextReceived, eventHandler)
|
||||
|
||||
fun WebApp.isInitDataSafe(botToken: String) = TelegramAPIUrlsKeeper(botToken).checkWebAppData(
|
||||
initData,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.inmo.tgbotapi.webapps.popup
|
||||
|
||||
import kotlin.js.json
|
||||
|
||||
|
||||
external interface ScanQrPopupParams {
|
||||
val text: String?
|
||||
}
|
||||
|
||||
fun ScanQrPopupParams(
|
||||
text: String? = null
|
||||
) = json(
|
||||
*listOfNotNull(
|
||||
("text" to text).takeIf { text != null }
|
||||
).toTypedArray()
|
||||
).unsafeCast<ScanQrPopupParams>()
|
||||
Reference in New Issue
Block a user