mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-12-04 21:35:44 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83ea4f6435 | |||
| 52204d8df1 | |||
| 81b9ccdf6a | |||
| fa74f12505 | |||
| be284c4d96 | |||
| 1769fcacfd | |||
| 4207d89c92 | |||
| 87ee2f280b | |||
| 3d458b2dc6 | |||
| ee1c7c6533 | |||
| 97d122c770 | |||
| 49da0faf45 | |||
| d426cb1210 | |||
| af83ac79e7 | |||
| 602f15c206 | |||
| c2f40534e6 | |||
| 5693d4d808 | |||
| 9fe55aa6ef | |||
| 8f817f1492 | |||
| 0fd146655d | |||
| 94e5f74a90 | |||
| b9bffbb71b | |||
| 5ec5c3bdfd | |||
| a5ed2a82bb | |||
| 1b7dd11e75 |
28
CHANGELOG.md
28
CHANGELOG.md
@@ -1,5 +1,33 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 0.38.12
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.9.17` -> `0.9.19`
|
||||
* `Coroutines`: `1.6.0` -> `1.6.1`
|
||||
* `Core`:
|
||||
* New type `TextedMediaContent` which will unite `TextedInput` and `MediaContent`
|
||||
* `MediaGroupContent` and all subsequent inheritors have been replaced to the package `dev.inmo.tgbotapi.types.message.content.media`
|
||||
* `MediaGroupContent` Now extends `TextedMediaContent` instead of `MediaContent`
|
||||
* Add `reply` functions with the texted content with including of text
|
||||
* `Utils`:
|
||||
* Improve work with retrieving of accumulated updates
|
||||
|
||||
## 0.38.11
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.9.16` -> `0.9.17`
|
||||
* `Klock`: `2.6.3` -> `2.7.0`
|
||||
* `Core`:
|
||||
* Fixes in `TextSourcesList` creating in from `RawMessageEntities`
|
||||
* Old ways to create keyboards (`matrix` and `row`) have been deprecated
|
||||
* `API`:
|
||||
* Add ability to `reply` with `Poll`
|
||||
* Add ability to `reply` with any `MessageContent`
|
||||
* Add ability to `reply` with any `TelegramMediaFile`
|
||||
|
||||
## 0.38.10
|
||||
|
||||
* `API`:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#january-31-2022)
|
||||
|
||||
| [](https://github.com/KotlinBy/awesome-kotlin) [](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [](https://forms.gle/2Hex2ynbHWHhi1KY7) [](https://t.me/InMoTelegramBotAPI) |
|
||||
| [](https://github.com/KotlinBy/awesome-kotlin) [](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) [](https://t.me/InMoTelegramBotAPI) |
|
||||
|:---:|
|
||||
| [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
||||
| [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
||||
|
||||
Hello! This is a set of libraries for working with Telegram Bot API.
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
kotlin_version=1.6.10
|
||||
kotlin_coroutines_version=1.6.0
|
||||
kotlin_coroutines_version=1.6.1
|
||||
kotlin_serialisation_runtime_version=1.3.2
|
||||
klock_version=2.6.3
|
||||
klock_version=2.7.0
|
||||
uuid_version=0.4.0
|
||||
ktor_version=1.6.8
|
||||
|
||||
micro_utils_version=0.9.16
|
||||
micro_utils_version=0.9.19
|
||||
|
||||
javax_activation_version=1.1.1
|
||||
|
||||
@@ -20,6 +20,6 @@ javax_activation_version=1.1.1
|
||||
dokka_version=1.6.10
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=0.38.10
|
||||
library_version=0.38.12
|
||||
|
||||
github_release_plugin_version=2.2.12
|
||||
|
||||
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.4.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
|
||||
@@ -2,18 +2,14 @@ package dev.inmo.tgbotapi.extensions.api.send
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup
|
||||
import dev.inmo.tgbotapi.requests.send.CopyMessage
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.MediaGroupUpdate
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
||||
import dev.inmo.tgbotapi.requests.send.media.rawSendingMediaGroupsWarning
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||
@@ -17,10 +18,14 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.dice.DiceAnimationType
|
||||
import dev.inmo.tgbotapi.types.files.*
|
||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
||||
import dev.inmo.tgbotapi.types.games.Game
|
||||
import dev.inmo.tgbotapi.types.location.StaticLocation
|
||||
import dev.inmo.tgbotapi.types.location.*
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
||||
import dev.inmo.tgbotapi.types.payments.abstracts.Currency
|
||||
import dev.inmo.tgbotapi.types.polls.*
|
||||
@@ -118,6 +123,7 @@ suspend inline fun TelegramBot.reply(
|
||||
longitude: Double,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(
|
||||
to.chat,
|
||||
@@ -125,6 +131,7 @@ suspend inline fun TelegramBot.reply(
|
||||
longitude,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
allowSendingWithoutReply,
|
||||
to.messageId,
|
||||
replyMarkup
|
||||
)
|
||||
@@ -138,12 +145,14 @@ suspend inline fun TelegramBot.reply(
|
||||
location: StaticLocation,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(
|
||||
to.chat,
|
||||
location,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
allowSendingWithoutReply,
|
||||
to.messageId,
|
||||
replyMarkup
|
||||
)
|
||||
@@ -887,6 +896,52 @@ suspend inline fun TelegramBot.reply(
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendQuizPoll(to.chat, isClosed, quizPoll, question, options, correctOptionId, isAnonymous, entities, closeInfo, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
poll: Poll,
|
||||
isClosed: Boolean = false,
|
||||
question: String = poll.question,
|
||||
options: List<String> = poll.options.map { it.text },
|
||||
isAnonymous: Boolean = poll.isAnonymous,
|
||||
closeInfo: ScheduledCloseInfo? = null,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = when (poll) {
|
||||
is RegularPoll -> reply(
|
||||
to = to,
|
||||
poll = poll,
|
||||
isClosed = isClosed,
|
||||
question = question,
|
||||
options = options,
|
||||
isAnonymous = isAnonymous,
|
||||
allowMultipleAnswers = isAnonymous,
|
||||
closeInfo = closeInfo,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is UnknownPollType -> error("Unable to send poll with unknown type ($poll)")
|
||||
is QuizPoll -> reply(
|
||||
to = to,
|
||||
quizPoll = poll,
|
||||
entities = poll.textSources,
|
||||
isClosed = isClosed,
|
||||
question = question,
|
||||
options = options,
|
||||
isAnonymous = isAnonymous,
|
||||
closeInfo = closeInfo,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
suspend inline fun TelegramBot.reply(
|
||||
to: Message,
|
||||
fromChatId: ChatIdentifier,
|
||||
@@ -921,3 +976,248 @@ suspend inline fun TelegramBot.reply(
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = reply(to, copy.chat.id, copy.messageId, text, parseMode, disableNotification, protectContent, allowSendingWithoutReply, replyMarkup)
|
||||
|
||||
suspend fun TelegramBot.reply(
|
||||
to: Message,
|
||||
content: MessageContent,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) {
|
||||
execute(
|
||||
content.createResend(
|
||||
to.chat.id,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
to.messageId,
|
||||
allowSendingWithoutReply,
|
||||
replyMarkup
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun TelegramBot.reply(
|
||||
to: Message,
|
||||
mediaFile: TelegramMediaFile,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) {
|
||||
when (mediaFile) {
|
||||
is AudioFile -> reply(
|
||||
to = to,
|
||||
audio = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is AnimationFile -> reply(
|
||||
to = to,
|
||||
animation = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is VoiceFile -> reply(
|
||||
to = to,
|
||||
voice = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is VideoFile -> reply(
|
||||
to = to,
|
||||
video = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is VideoNoteFile -> reply(
|
||||
to = to,
|
||||
videoNote = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is DocumentFile -> reply(
|
||||
to = to,
|
||||
document = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is Sticker -> reply(
|
||||
to = to,
|
||||
sticker = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is PhotoSize -> reply(
|
||||
to = to,
|
||||
photoSize = mediaFile,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
else -> reply(
|
||||
to = to,
|
||||
document = mediaFile.asDocumentFile(),
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun TelegramBot.reply(
|
||||
to: Message,
|
||||
content: TextedMediaContent,
|
||||
text: String?,
|
||||
parseMode: ParseMode? = null,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) {
|
||||
when (content) {
|
||||
is VoiceContent -> reply(
|
||||
to = to,
|
||||
voice = content.media,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is AudioMediaGroupContent -> reply(
|
||||
to = to,
|
||||
audio = content.media,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is PhotoContent -> reply(
|
||||
to = to,
|
||||
photoSize = content.media,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is VideoContent -> reply(
|
||||
to = to,
|
||||
video = content.media,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is AnimationContent -> reply(
|
||||
to = to,
|
||||
animation = content.media,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
else -> reply(
|
||||
to = to,
|
||||
document = content.media.asDocumentFile(),
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun TelegramBot.reply(
|
||||
to: Message,
|
||||
content: TextedMediaContent,
|
||||
entities: List<TextSource>,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) {
|
||||
when (content) {
|
||||
is VoiceContent -> reply(
|
||||
to = to,
|
||||
voice = content.media,
|
||||
entities = entities,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is AudioMediaGroupContent -> reply(
|
||||
to = to,
|
||||
audio = content.media,
|
||||
entities = entities,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is PhotoContent -> reply(
|
||||
to = to,
|
||||
photoSize = content.media,
|
||||
entities = entities,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is VideoContent -> reply(
|
||||
to = to,
|
||||
video = content.media,
|
||||
entities = entities,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
is AnimationContent -> reply(
|
||||
to = to,
|
||||
animation = content.media,
|
||||
entities = entities,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
else -> reply(
|
||||
to = to,
|
||||
document = content.media.asDocumentFile(),
|
||||
entities = entities,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
longitude: Double,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = execute(
|
||||
@@ -27,6 +28,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
longitude,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyToMessageId = replyToMessageId,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
@@ -41,6 +43,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
location: StaticLocation,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(
|
||||
@@ -49,6 +52,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
location.longitude,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
allowSendingWithoutReply,
|
||||
replyToMessageId,
|
||||
replyMarkup
|
||||
)
|
||||
@@ -63,6 +67,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
longitude: Double,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(
|
||||
@@ -71,6 +76,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
longitude,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
allowSendingWithoutReply,
|
||||
replyToMessageId,
|
||||
replyMarkup
|
||||
)
|
||||
@@ -84,6 +90,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
location: StaticLocation,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(
|
||||
@@ -92,6 +99,7 @@ suspend fun TelegramBot.sendLocation(
|
||||
location.longitude,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
allowSendingWithoutReply,
|
||||
replyToMessageId,
|
||||
replyMarkup
|
||||
)
|
||||
@@ -106,9 +114,10 @@ suspend fun TelegramBot.sendStaticLocation(
|
||||
longitude: Double,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(chatId, latitude, longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
||||
) = sendLocation(chatId, latitude, longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -119,9 +128,10 @@ suspend fun TelegramBot.sendStaticLocation(
|
||||
location: StaticLocation,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(chatId, location.latitude, location.longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
||||
) = sendLocation(chatId, location.latitude, location.longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -133,9 +143,10 @@ suspend fun TelegramBot.sendStaticLocation(
|
||||
longitude: Double,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(chat.id, latitude, longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
||||
) = sendLocation(chat.id, latitude, longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||
|
||||
/**
|
||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||
@@ -146,6 +157,7 @@ suspend fun TelegramBot.sendStaticLocation(
|
||||
location: StaticLocation,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
replyToMessageId: MessageIdentifier? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
) = sendLocation(chat.id, location.latitude, location.longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
||||
) = sendLocation(chat.id, location.latitude, location.longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||
|
||||
@@ -6,8 +6,8 @@ import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
|
||||
@@ -11,12 +11,15 @@ import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
||||
|
||||
@@ -198,6 +201,14 @@ suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
||||
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||
suspend fun BehaviourContext.waitTextedMediaContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
|
||||
mapper: CommonMessageToContentMapper<TextedMediaContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||
suspend fun BehaviourContext.waitAnimation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
|
||||
@@ -12,6 +12,10 @@ import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
|
||||
import kotlinx.coroutines.flow.toList
|
||||
@@ -173,6 +177,14 @@ suspend fun BehaviourContext.waitEditedVisualMediaGroupContent(
|
||||
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
||||
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
|
||||
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||
suspend fun BehaviourContext.waitEditedTextedMediaContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
|
||||
mapper: CommonMessageToContentMapper<TextedMediaContent>? = null
|
||||
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||
suspend fun BehaviourContext.waitEditedAnimation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
|
||||
@@ -5,8 +5,11 @@ import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.toList
|
||||
|
||||
@@ -14,6 +14,8 @@ import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||
@@ -326,6 +328,30 @@ suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
|
||||
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.onTextedMediaContent(
|
||||
initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedMediaContent>, Update> = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in CommonMessage<TextedMediaContent>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedMediaContent>>
|
||||
) = onContent(
|
||||
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,
|
||||
|
||||
@@ -27,6 +27,8 @@ import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
@@ -262,6 +264,30 @@ suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
|
||||
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.onEditedTextedMediaContent(
|
||||
initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedMediaContent>, Update> = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in CommonMessage<TextedMediaContent>, Any> = ByChatMessageMarkerFactory,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedMediaContent>>
|
||||
)= onEditedContent(
|
||||
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,
|
||||
|
||||
@@ -9,9 +9,11 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByC
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||
import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
|
||||
@@ -20,11 +20,11 @@ internal data class RawMessageEntity(
|
||||
|
||||
internal fun RawMessageEntity.asTextSource(
|
||||
source: String,
|
||||
subParts: TextSourcesList
|
||||
subParts: List<Pair<Int, TextSource>>
|
||||
): TextSource {
|
||||
val sourceSubstring: String = source.substring(range)
|
||||
val subPartsWithRegulars by lazy {
|
||||
subParts.fillWithRegulars(sourceSubstring)
|
||||
subParts.map { (it.first - offset) to it.second }.fillWithRegulars(sourceSubstring)
|
||||
}
|
||||
return when (type) {
|
||||
"mention" -> MentionTextSource(sourceSubstring, subPartsWithRegulars)
|
||||
@@ -58,16 +58,14 @@ private inline operator fun <T : Comparable<T>> ClosedRange<T>.contains(other: C
|
||||
return start <= other.start && endInclusive >= other.endInclusive
|
||||
}
|
||||
|
||||
internal fun TextSourcesList.fillWithRegulars(source: String): TextSourcesList {
|
||||
internal fun List<Pair<Int, TextSource>>.fillWithRegulars(source: String): TextSourcesList {
|
||||
var index = 0
|
||||
val result = mutableListOf<TextSource>()
|
||||
for (i in 0 until size) {
|
||||
val textSource = get(i)
|
||||
val thisSourceInStart = source.startsWith(textSource.source, index)
|
||||
if (!thisSourceInStart) {
|
||||
val regularEndIndex = source.indexOf(textSource.source, index)
|
||||
result.add(regular(source.substring(index, regularEndIndex)))
|
||||
index = regularEndIndex
|
||||
for (i in indices) {
|
||||
val (offset, textSource) = get(i)
|
||||
if (offset - index > 0) {
|
||||
result.add(regular(source.substring(index, offset)))
|
||||
index = offset
|
||||
}
|
||||
result.add(textSource)
|
||||
index += textSource.source.length
|
||||
@@ -83,9 +81,9 @@ internal fun TextSourcesList.fillWithRegulars(source: String): TextSourcesList {
|
||||
private fun createTextSources(
|
||||
originalFullString: String,
|
||||
entities: RawMessageEntities
|
||||
): TextSourcesList {
|
||||
): List<Pair<Int, TextSource>> {
|
||||
val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } }
|
||||
val resultList = mutableListOf<TextSource>()
|
||||
val resultList = mutableListOf<Pair<Int, TextSource>>()
|
||||
|
||||
while (mutableEntities.isNotEmpty()) {
|
||||
var parent = mutableEntities.removeFirst()
|
||||
@@ -129,7 +127,7 @@ private fun createTextSources(
|
||||
emptyList()
|
||||
}
|
||||
resultList.add(
|
||||
parent.asTextSource(
|
||||
parent.offset to parent.asTextSource(
|
||||
originalFullString,
|
||||
subtextSources
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
||||
import dev.inmo.tgbotapi.utils.MimeType
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -24,11 +25,15 @@ data class DocumentFile(
|
||||
) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, CustomNamedMediaFile
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun TelegramMediaFile.asDocumentFile() = DocumentFile(
|
||||
fileId,
|
||||
fileUniqueId,
|
||||
fileSize,
|
||||
(this as? ThumbedMediaFile) ?.thumb,
|
||||
(this as? MimedMediaFile) ?.mimeType,
|
||||
(this as? CustomNamedMediaFile) ?.fileName
|
||||
)
|
||||
inline fun TelegramMediaFile.asDocumentFile() = if (this is DocumentFile) {
|
||||
this
|
||||
} else {
|
||||
DocumentFile(
|
||||
fileId,
|
||||
fileUniqueId,
|
||||
fileSize,
|
||||
(this as? ThumbedMediaFile) ?.thumb,
|
||||
(this as? MimedMediaFile) ?.mimeType,
|
||||
(this as? CustomNamedMediaFile) ?.fileName
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
|
||||
data class ChannelMediaGroupMessage<T : MediaGroupContent>(
|
||||
override val messageId: MessageIdentifier,
|
||||
|
||||
@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
|
||||
data class CommonMediaGroupMessage<T : MediaGroupContent>(
|
||||
override val messageId: MessageIdentifier,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.MediaGroupIdentifier
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
|
||||
interface MediaGroupMessage<T : MediaGroupContent> : CommonMessage<T> {
|
||||
val mediaGroupId: MediaGroupIdentifier
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.abstracts
|
||||
|
||||
@Deprecated("This class has been moved to the other package", ReplaceWith("AudioMediaGroupContent", "dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent"))
|
||||
typealias AudioMediaGroupContent = dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.abstracts
|
||||
|
||||
@Deprecated("This class has been moved to the other package", ReplaceWith("DocumentMediaGroupContent", "dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent"))
|
||||
typealias DocumentMediaGroupContent = dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
@@ -1,18 +1,4 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
|
||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||
|
||||
interface MediaGroupContent : MediaContent, TextedInput {
|
||||
fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
|
||||
}
|
||||
|
||||
interface VisualMediaGroupContent : MediaGroupContent {
|
||||
override fun toMediaGroupMemberInputMedia(): VisualMediaGroupMemberInputMedia
|
||||
}
|
||||
interface AudioMediaGroupContent : MediaGroupContent {
|
||||
override fun toMediaGroupMemberInputMedia(): AudioMediaGroupMemberInputMedia
|
||||
}
|
||||
interface DocumentMediaGroupContent : MediaGroupContent {
|
||||
override fun toMediaGroupMemberInputMedia(): DocumentMediaGroupMemberInputMedia
|
||||
}
|
||||
@Deprecated("This class has been moved to the other package", ReplaceWith("MediaGroupContent", "dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent"))
|
||||
typealias MediaGroupContent = dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.abstracts
|
||||
|
||||
@Deprecated("This class has been moved to the other package", ReplaceWith("VisualMediaGroupContent", "dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent"))
|
||||
typealias VisualMediaGroupContent = dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
@@ -20,7 +20,7 @@ data class AnimationContent(
|
||||
val includedDocument: DocumentFile?,
|
||||
override val text: String?,
|
||||
override val textSources: TextSourcesList = emptyList()
|
||||
) : MediaContent, TextedInput {
|
||||
) : TextedMediaContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
disableNotification: Boolean,
|
||||
|
||||
@@ -10,7 +10,6 @@ import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.AudioMediaGroupContent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.InputMedia.AudioMediaGroupMemberInputMedia
|
||||
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||
|
||||
interface AudioMediaGroupContent : MediaGroupContent {
|
||||
override val media: AudioFile
|
||||
|
||||
override fun toMediaGroupMemberInputMedia(): AudioMediaGroupMemberInputMedia
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||
import dev.inmo.tgbotapi.types.files.asDocumentFile
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||
|
||||
interface DocumentMediaGroupContent : MediaGroupContent {
|
||||
override val media: DocumentFile
|
||||
|
||||
override fun toMediaGroupMemberInputMedia(): DocumentMediaGroupMemberInputMedia
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia
|
||||
|
||||
interface MediaGroupContent : TextedMediaContent {
|
||||
fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.files.*
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaCollectionContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.media
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||
|
||||
sealed interface TextedMediaContent : MediaContent, TextedInput
|
||||
@@ -10,7 +10,6 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||
import dev.inmo.tgbotapi.types.files.toInputMediaVideo
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.content.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.InputMedia.VisualMediaGroupMemberInputMedia
|
||||
|
||||
interface VisualMediaGroupContent : MediaGroupContent {
|
||||
override fun toMediaGroupMemberInputMedia(): VisualMediaGroupMemberInputMedia
|
||||
}
|
||||
@@ -18,7 +18,7 @@ data class VoiceContent(
|
||||
override val media: VoiceFile,
|
||||
override val text: String? = null,
|
||||
override val textSources: TextSourcesList = emptyList()
|
||||
) : MediaContent, TextedInput {
|
||||
) : TextedMediaContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
disableNotification: Boolean,
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
|
||||
|
||||
import dev.inmo.tgbotapi.types.UpdateIdentifier
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
|
||||
|
||||
data class ChannelPostMediaGroupUpdate(
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
|
||||
|
||||
import dev.inmo.tgbotapi.types.UpdateIdentifier
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.EditChannelPostUpdate
|
||||
|
||||
data class EditChannelPostMediaGroupUpdate(
|
||||
@@ -10,4 +10,4 @@ data class EditChannelPostMediaGroupUpdate(
|
||||
) : EditMediaGroupUpdate {
|
||||
override val updateId: UpdateIdentifier = origin.updateId
|
||||
override val data: MediaGroupMessage<MediaGroupContent> = origin.data as MediaGroupMessage<MediaGroupContent>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
|
||||
|
||||
import dev.inmo.tgbotapi.types.UpdateIdentifier
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.EditMessageUpdate
|
||||
|
||||
data class EditMessageMediaGroupUpdate(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.*
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
|
||||
|
||||
import dev.inmo.tgbotapi.types.UpdateIdentifier
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
|
||||
|
||||
data class MessageMediaGroupUpdate(
|
||||
@@ -10,4 +10,4 @@ data class MessageMediaGroupUpdate(
|
||||
) : SentMediaGroupUpdate {
|
||||
override val updateId: UpdateIdentifier = origins.last().updateId
|
||||
override val data: List<MediaGroupMessage<MediaGroupContent>> = origins.mapNotNull { it.data as? MediaGroupMessage<MediaGroupContent> }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,34 +2,69 @@ package dev.inmo.tgbotapi.utils
|
||||
|
||||
import dev.inmo.tgbotapi.types.buttons.Matrix
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardRowBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardRowBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
fun <T> row(block: RowBuilder<T>.() -> Unit): List<T> {
|
||||
return RowBuilder<T>().also(block).row
|
||||
}
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardRowBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardRowBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
fun <T> MatrixBuilder<T>.row(block: RowBuilder<T>.() -> Unit) {
|
||||
add(RowBuilder<T>().also(block).row)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardRowBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardRowBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
fun <T> MatrixBuilder<T>.row(vararg elements: T) {
|
||||
add(elements.toList())
|
||||
}
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
fun <T> matrix(block: MatrixBuilder<T>.() -> Unit): Matrix<T> {
|
||||
return MatrixBuilder<T>().also(block).matrix
|
||||
}
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
fun <T> flatMatrix(block: RowBuilder<T>.() -> Unit): Matrix<T> {
|
||||
return MatrixBuilder<T>().apply {
|
||||
row(block)
|
||||
}.matrix
|
||||
}
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
fun <T> flatMatrix(vararg elements: T): Matrix<T> {
|
||||
return MatrixBuilder<T>().apply {
|
||||
row { elements.forEach { +it } }
|
||||
}.matrix
|
||||
}
|
||||
|
||||
/**
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardRowBuilder
|
||||
* @see dev.inmo.tgbotapi.extensions.utils.types.buttons.ReplyKeyboardRowBuilder
|
||||
*/
|
||||
@Deprecated("This functionality will be removed soon")
|
||||
operator fun <T> RowBuilder<T>.plus(t: T) = add(t)
|
||||
|
||||
open class RowBuilder<T> {
|
||||
|
||||
@@ -3,43 +3,43 @@ package dev.inmo.tgbotapi.types.MessageEntity
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
const val testText = "It is simple hello world with #tag and @mention"
|
||||
const val formattedV2Text = "It *_is_ ~__simple__~* ||hello world|| with \\#tag and @mention"
|
||||
const val formattedHtmlText = "It <b><i>is</i> <s><u>simple</u></s></b> <span class=\"tg-spoiler\">hello world</span> with #tag and @mention"
|
||||
const val testText = "It (is?) is simple hello world with #tag and @mention"
|
||||
const val formattedV2Text = "It \\(is?\\) *_is_ ~__simple__~* ||hello world|| with \\#tag and @mention"
|
||||
const val formattedHtmlText = "It (is?) <b><i>is</i> <s><u>simple</u></s></b> <span class=\"tg-spoiler\">hello world</span> with #tag and @mention"
|
||||
internal val testTextEntities = listOf(
|
||||
RawMessageEntity(
|
||||
"bold",
|
||||
3,
|
||||
9,
|
||||
9
|
||||
),
|
||||
RawMessageEntity(
|
||||
"italic",
|
||||
3,
|
||||
9,
|
||||
2
|
||||
),
|
||||
RawMessageEntity(
|
||||
"strikethrough",
|
||||
6,
|
||||
12,
|
||||
6
|
||||
),
|
||||
RawMessageEntity(
|
||||
"underline",
|
||||
6,
|
||||
12,
|
||||
6
|
||||
),
|
||||
RawMessageEntity(
|
||||
"spoiler",
|
||||
13,
|
||||
19,
|
||||
11
|
||||
),
|
||||
RawMessageEntity(
|
||||
"hashtag",
|
||||
30,
|
||||
36,
|
||||
4
|
||||
),
|
||||
RawMessageEntity(
|
||||
"mention",
|
||||
39,
|
||||
45,
|
||||
8
|
||||
)
|
||||
)
|
||||
|
||||
@@ -2,8 +2,7 @@ package dev.inmo.tgbotapi.types.MessageEntity
|
||||
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.*
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.*
|
||||
|
||||
class StringFormattingTests {
|
||||
@Test
|
||||
@@ -38,7 +37,7 @@ class StringFormattingTests {
|
||||
|
||||
@Test
|
||||
fun testThatCreatingOfStringWithSimpleDSLWorksCorrectly() {
|
||||
val sources: TextSourcesList = regular("It ") +
|
||||
val sources: TextSourcesList = regular("It (is?) ") +
|
||||
bold(italic("is") +
|
||||
" " +
|
||||
strikethrough(underline("simple"))) +
|
||||
@@ -53,4 +52,43 @@ class StringFormattingTests {
|
||||
assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first())
|
||||
assertEquals(formattedHtmlText, sources.toHtmlTexts().first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testForRepeatingWordsInOneSentenceWithTheSecondOneFormatted() {
|
||||
val sourceText = "link link"
|
||||
val messageEntities = listOf(
|
||||
RawMessageEntity("bold", 5, 4),
|
||||
RawMessageEntity("text_link", 6, 2, "google.com")
|
||||
)
|
||||
val textSources = messageEntities.asTextSources(sourceText)
|
||||
val (regular, bold) = textSources
|
||||
assertTrue(regular is RegularTextSource)
|
||||
assertTrue(bold is BoldTextSource)
|
||||
assertTrue(regular.source == "link ")
|
||||
assertTrue(bold.source == "link")
|
||||
assertTrue((bold.subsources[0] as? RegularTextSource) ?.source == "l")
|
||||
assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.source == "in")
|
||||
assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.url == "google.com")
|
||||
assertTrue((bold.subsources[2] as? RegularTextSource) ?.source == "k")
|
||||
assertTrue(bold.subsources.size == 3)
|
||||
assertTrue(textSources.size == 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testForRepeatingWordsInOneSentenceWithTheSecondOneFormattedInsideOfFormatting() {
|
||||
val sourceText = "text"
|
||||
val messageEntities = listOf(
|
||||
RawMessageEntity("bold", 0, 4),
|
||||
RawMessageEntity("text_link", 3, 1, "google.com")
|
||||
)
|
||||
val textSources = messageEntities.asTextSources(sourceText)
|
||||
val (bold) = textSources
|
||||
assertTrue(bold is BoldTextSource)
|
||||
assertTrue(bold.source == "text")
|
||||
assertTrue((bold.subsources[0] as? RegularTextSource) ?.source == "tex")
|
||||
assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.source == "t")
|
||||
assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.url == "google.com")
|
||||
assertTrue(bold.subsources.size == 2)
|
||||
assertTrue(textSources.size == 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
||||
import dev.inmo.tgbotapi.types.passport.*
|
||||
@@ -2671,6 +2675,17 @@ inline fun ResendableContent.asMediaCollectionContent(): MediaCollectionContent<
|
||||
inline fun ResendableContent.requireMediaCollectionContent(): MediaCollectionContent<TelegramMediaFile> =
|
||||
this as MediaCollectionContent<TelegramMediaFile>
|
||||
|
||||
@PreviewFeature
|
||||
inline fun <T> ResendableContent.whenTextedMediaContent(block: (TextedMediaContent) -> T) = asTextedMediaContent() ?.let(block)
|
||||
|
||||
@PreviewFeature
|
||||
inline fun ResendableContent.asTextedMediaContent(): TextedMediaContent? =
|
||||
this as? TextedMediaContent
|
||||
|
||||
@PreviewFeature
|
||||
inline fun ResendableContent.requireTextedMediaContent(): TextedMediaContent =
|
||||
this as TextedMediaContent
|
||||
|
||||
@PreviewFeature
|
||||
inline fun <T> ResendableContent.whenMediaContent(block: (MediaContent) -> T) = asMediaContent() ?.let(block)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package dev.inmo.tgbotapi.extensions.utils
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
|
||||
inline fun <reified T : MessageContent> ContentMessage<*>.withContent() = if (content is T) { this as ContentMessage<T> } else { null }
|
||||
inline fun <reified T : MessageContent> ContentMessage<*>.requireWithContent() = withContent<T>()!!
|
||||
|
||||
@@ -8,6 +8,8 @@ import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||
|
||||
@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.message.ForwardInfo
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||
|
||||
val List<CommonMessage<out MediaGroupContent>>.forwardInfo: ForwardInfo?
|
||||
|
||||
@@ -15,6 +15,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
import dev.inmo.tgbotapi.updateshandlers.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import io.ktor.client.features.HttpRequestTimeoutException
|
||||
import io.ktor.utils.io.CancellationException
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
@@ -89,6 +90,29 @@ fun TelegramBot.startGettingOfUpdatesByLongPolling(
|
||||
updatesReceiver
|
||||
)
|
||||
|
||||
/**
|
||||
* @return [kotlinx.coroutines.flow.Flow] which will emit updates to the collector while they will be accumulated. Works
|
||||
* the same as [longPollingFlow], but it will cancel the flow after the first one [HttpRequestTimeoutException]
|
||||
*/
|
||||
fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
||||
avoidInlineQueries: Boolean = false,
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
allowedUpdates: List<String>? = null
|
||||
): Flow<Update> = longPollingFlow(
|
||||
timeoutSeconds = 0,
|
||||
exceptionsHandler = {
|
||||
if (it is HttpRequestTimeoutException) {
|
||||
throw CancellationException("Cancel due to absence of new updates")
|
||||
} else {
|
||||
exceptionsHandler ?.invoke(it)
|
||||
}
|
||||
},
|
||||
allowedUpdates = allowedUpdates
|
||||
).filter {
|
||||
!(it is InlineQueryUpdate && avoidInlineQueries || it is CallbackQueryUpdate && avoidCallbackQueries)
|
||||
}
|
||||
|
||||
fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries: Boolean = false,
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
@@ -96,51 +120,15 @@ fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||
allowedUpdates: List<String>? = null,
|
||||
updatesReceiver: UpdateReceiver<Update>
|
||||
): Job = scope.launch {
|
||||
safelyWithoutExceptions {
|
||||
startGettingOfUpdatesByLongPolling(
|
||||
0,
|
||||
CoroutineScope(coroutineContext + SupervisorJob()),
|
||||
{
|
||||
if (it is HttpRequestTimeoutException) {
|
||||
throw CancellationException("Cancel due to absence of new updates")
|
||||
} else {
|
||||
exceptionsHandler ?.invoke(it)
|
||||
}
|
||||
},
|
||||
allowedUpdates
|
||||
) {
|
||||
when {
|
||||
it is InlineQueryUpdate && avoidInlineQueries ||
|
||||
it is CallbackQueryUpdate && avoidCallbackQueries -> return@startGettingOfUpdatesByLongPolling
|
||||
else -> updatesReceiver(it)
|
||||
}
|
||||
}.join()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return [kotlinx.coroutines.flow.Flow] which will emit updates to the collector while they will be accumulated. Works
|
||||
* the same as [retrieveAccumulatedUpdates], but pass [kotlinx.coroutines.flow.FlowCollector.emit] as a callback
|
||||
*/
|
||||
fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
||||
avoidInlineQueries: Boolean = false,
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
allowedUpdates: List<String>? = null
|
||||
): Flow<Update> = channelFlow {
|
||||
val parentContext = kotlin.coroutines.coroutineContext
|
||||
channel.apply {
|
||||
retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries,
|
||||
avoidCallbackQueries,
|
||||
CoroutineScope(parentContext),
|
||||
exceptionsHandler,
|
||||
allowedUpdates,
|
||||
::send
|
||||
).join()
|
||||
close()
|
||||
}
|
||||
): Job = createAccumulatedUpdatesRetrieverFlow(
|
||||
avoidInlineQueries,
|
||||
avoidCallbackQueries,
|
||||
exceptionsHandler,
|
||||
allowedUpdates
|
||||
).subscribeSafelyWithoutExceptions(
|
||||
scope.LinkedSupervisorScope()
|
||||
) {
|
||||
updatesReceiver(it)
|
||||
}
|
||||
|
||||
fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
@@ -149,9 +137,30 @@ fun TelegramBot.retrieveAccumulatedUpdates(
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null
|
||||
) = flowsUpdatesFilter.run {
|
||||
retrieveAccumulatedUpdates(avoidInlineQueries, avoidCallbackQueries, scope, exceptionsHandler, allowedUpdates, asUpdateReceiver)
|
||||
}
|
||||
) = retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries,
|
||||
avoidCallbackQueries,
|
||||
scope,
|
||||
exceptionsHandler,
|
||||
flowsUpdatesFilter.allowedUpdates,
|
||||
flowsUpdatesFilter.asUpdateReceiver
|
||||
)
|
||||
|
||||
suspend fun TelegramBot.flushAccumulatedUpdates(
|
||||
avoidInlineQueries: Boolean = false,
|
||||
avoidCallbackQueries: Boolean = false,
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||
allowedUpdates: List<String>? = null,
|
||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
updatesReceiver: UpdateReceiver<Update> = {}
|
||||
) = retrieveAccumulatedUpdates(
|
||||
avoidInlineQueries,
|
||||
avoidCallbackQueries,
|
||||
scope,
|
||||
exceptionsHandler,
|
||||
allowedUpdates,
|
||||
updatesReceiver
|
||||
).join()
|
||||
|
||||
/**
|
||||
* Will [startGettingOfUpdatesByLongPolling] using incoming [flowsUpdatesFilter]. It is assumed that you ALREADY CONFIGURE
|
||||
|
||||
Reference in New Issue
Block a user