mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-17 04:20:13 +00:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65bcf83517 | |||
| f07a179448 | |||
| ed2c447730 | |||
| cb4c48d025 | |||
| 1a21fa85ac | |||
| 191fa5406d | |||
| 6959dacfc4 | |||
| ced11ab336 | |||
| 6686aef4fa | |||
| 9ede545e56 | |||
| a74066cf62 | |||
| 0a7e99bbb3 | |||
| 913f584469 | |||
| 20278804bf | |||
| 631f1b9427 | |||
| 5e0106beb5 | |||
| d37e01f93e | |||
|
|
d4492ec7ac | ||
| 60d24259f4 | |||
| 8e6b3b7260 | |||
| e2cbd5ee0b | |||
| 1e87677ea7 | |||
| cb3494cb39 | |||
| ce81be9dcb | |||
| 2cc02c8c85 | |||
| f5b2ee79d6 | |||
| 0ba6ebb20f | |||
| 3d2df4e255 | |||
| 33b6ff1c1e | |||
| 2859f8ca2f | |||
| f1aa67ceda | |||
| 1c66d1e2fc | |||
| 44e6d7adbc | |||
| 61a6d4a880 | |||
| e37237cb71 | |||
| 9a5a196e41 | |||
| 68f6d8553c | |||
| 6fe8e73fca |
37
CHANGELOG.md
37
CHANGELOG.md
@@ -1,5 +1,42 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 7.1.3
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Serialization`: `1.5.0` -> `1.5.1`
|
||||||
|
* `MicroUtils`: `0.18.1` -> `0.18.4`
|
||||||
|
* `Core`:
|
||||||
|
* Actualize kdocs in `InputFile`
|
||||||
|
* `BehaviourBuilder`:
|
||||||
|
* Now it is possible to use `waitMediaContent`/`waitMediaContentMessage`/`onMediaContent`
|
||||||
|
* Add `onMention`/`waitMention` functionality
|
||||||
|
* Add opportunity to map content with extensions to `Flow`
|
||||||
|
|
||||||
|
## 7.1.2
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `MicroUtils`: `0.18.0` -> `0.18.1`
|
||||||
|
* `Core`:
|
||||||
|
* Now it is possible to serialize `Sticker`s
|
||||||
|
|
||||||
|
## 7.1.1
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Kotlin`: `1.8.20` -> `1.8.21`
|
||||||
|
* `MicroUtils`: `0.17.8` -> `0.18.0`
|
||||||
|
* `Utils`:
|
||||||
|
* Fixes in `makeLinkToMessage`
|
||||||
|
|
||||||
|
## 7.1.0
|
||||||
|
|
||||||
|
**This update contains changes according to the [Telegram Bot API 6.7](https://core.telegram.org/bots/api-changelog#april-21-2023)**
|
||||||
|
|
||||||
|
* `API`:
|
||||||
|
* Rename `editMessageCaption` to `editMessageMedia` due to wrong old naming
|
||||||
|
* Add `edit` extensions for `InlineMessageIdentifier`s
|
||||||
|
* `BehaviourBuilder`:
|
||||||
|
* `BehaviourContext` extensions `onDeepLink` and `waitDeepLinks` now can be used with `Regex` or `String` as first parameters
|
||||||
|
|
||||||
## 7.0.2
|
## 7.0.2
|
||||||
|
|
||||||
_This update brings experimental support of `linuxX64` and `mingwX64` platforms_
|
_This update brings experimental support of `linuxX64` and `mingwX64` platforms_
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#march-9-2023)
|
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#april-21-2023)
|
||||||
|
|
||||||
| Docs | [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
| Docs | [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
||||||
|:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
|
|:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
|
||||||
| Useful repos | [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) |
|
| Useful repos | [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) |
|
||||||
| Misc | [](https://github.com/KotlinBy/awesome-kotlin) [](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) |
|
| Misc | [](https://github.com/KotlinBy/awesome-kotlin) [](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) |
|
||||||
| Platforms |   |
|
| Platforms |   |
|
||||||
| Experimental Platforms |   |
|
| Experimental Platforms | [](https://kotlinlang.org/docs/native-target-support.html#tier-1) [](https://kotlinlang.org/docs/native-target-support.html#tier-1) |
|
||||||
|
|
||||||
<!--- [](https://t.me/ktgbotapi) --->
|
<!--- [](https://t.me/ktgbotapi) --->
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
|||||||
kotlin.incremental.js=true
|
kotlin.incremental.js=true
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=7.0.2
|
library_version=7.1.3
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
|
|
||||||
kotlin = "1.8.20"
|
kotlin = "1.8.21"
|
||||||
kotlin-serialization = "1.5.0"
|
kotlin-serialization = "1.5.1"
|
||||||
kotlin-coroutines = "1.6.4"
|
kotlin-coroutines = "1.6.4"
|
||||||
|
|
||||||
javax-activation = "1.1.1"
|
javax-activation = "1.1.1"
|
||||||
@@ -10,10 +10,10 @@ korlibs = "3.4.0"
|
|||||||
uuid = "0.7.0"
|
uuid = "0.7.0"
|
||||||
ktor = "2.3.0"
|
ktor = "2.3.0"
|
||||||
|
|
||||||
ksp = "1.8.20-1.0.11"
|
ksp = "1.8.21-1.0.11"
|
||||||
kotlin-poet = "1.13.0"
|
kotlin-poet = "1.13.2"
|
||||||
|
|
||||||
microutils = "0.17.8"
|
microutils = "0.18.4"
|
||||||
|
|
||||||
github-release-plugin = "2.4.1"
|
github-release-plugin = "2.4.1"
|
||||||
dokka = "1.8.10"
|
dokka = "1.8.10"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.extensions.api.answers
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.answers.AnswerInlineQuery
|
import dev.inmo.tgbotapi.requests.answers.AnswerInlineQuery
|
||||||
|
import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
|
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
|
||||||
import dev.inmo.tgbotapi.types.InlineQueryIdentifier
|
import dev.inmo.tgbotapi.types.InlineQueryIdentifier
|
||||||
@@ -12,8 +13,37 @@ suspend fun TelegramBot.answerInlineQuery(
|
|||||||
cachedTime: Int? = null,
|
cachedTime: Int? = null,
|
||||||
isPersonal: Boolean? = null,
|
isPersonal: Boolean? = null,
|
||||||
nextOffset: String? = null,
|
nextOffset: String? = null,
|
||||||
switchPmText: String? = null,
|
button: InlineQueryResultsButton? = null
|
||||||
switchPmParameter: String? = null
|
) = execute(
|
||||||
|
AnswerInlineQuery(inlineQueryID, results, cachedTime, isPersonal, nextOffset, button)
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.answerInlineQuery(
|
||||||
|
inlineQuery: InlineQuery,
|
||||||
|
results: List<InlineQueryResult> = emptyList(),
|
||||||
|
cachedTime: Int? = null,
|
||||||
|
isPersonal: Boolean? = null,
|
||||||
|
nextOffset: String? = null,
|
||||||
|
button: InlineQueryResultsButton? = null
|
||||||
|
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, button)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.answer(
|
||||||
|
inlineQuery: InlineQuery,
|
||||||
|
results: List<InlineQueryResult> = emptyList(),
|
||||||
|
cachedTime: Int? = null,
|
||||||
|
isPersonal: Boolean? = null,
|
||||||
|
nextOffset: String? = null,
|
||||||
|
button: InlineQueryResultsButton? = null
|
||||||
|
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, button)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.answerInlineQuery(
|
||||||
|
inlineQueryID: InlineQueryIdentifier,
|
||||||
|
results: List<InlineQueryResult> = emptyList(),
|
||||||
|
cachedTime: Int? = null,
|
||||||
|
isPersonal: Boolean? = null,
|
||||||
|
nextOffset: String? = null,
|
||||||
|
switchPmText: String?,
|
||||||
|
switchPmParameter: String?
|
||||||
) = execute(
|
) = execute(
|
||||||
AnswerInlineQuery(inlineQueryID, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
AnswerInlineQuery(inlineQueryID, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
||||||
)
|
)
|
||||||
@@ -24,8 +54,8 @@ suspend fun TelegramBot.answerInlineQuery(
|
|||||||
cachedTime: Int? = null,
|
cachedTime: Int? = null,
|
||||||
isPersonal: Boolean? = null,
|
isPersonal: Boolean? = null,
|
||||||
nextOffset: String? = null,
|
nextOffset: String? = null,
|
||||||
switchPmText: String? = null,
|
switchPmText: String?,
|
||||||
switchPmParameter: String? = null
|
switchPmParameter: String?
|
||||||
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
||||||
|
|
||||||
suspend fun TelegramBot.answer(
|
suspend fun TelegramBot.answer(
|
||||||
@@ -34,6 +64,6 @@ suspend fun TelegramBot.answer(
|
|||||||
cachedTime: Int? = null,
|
cachedTime: Int? = null,
|
||||||
isPersonal: Boolean? = null,
|
isPersonal: Boolean? = null,
|
||||||
nextOffset: String? = null,
|
nextOffset: String? = null,
|
||||||
switchPmText: String? = null,
|
switchPmText: String?,
|
||||||
switchPmParameter: String? = null
|
switchPmParameter: String?
|
||||||
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.bot
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.GetMyName
|
||||||
|
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||||
|
import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getMyName(
|
||||||
|
languageCode: IetfLanguageCode? = null
|
||||||
|
) = execute(GetMyName(languageCode))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getMyName(
|
||||||
|
languageCode: String?
|
||||||
|
) = getMyName(languageCode ?.let(::IetfLanguageCode))
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.bot
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.GetMyName
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.SetMyName
|
||||||
|
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||||
|
import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setMyName(
|
||||||
|
name: String? = null,
|
||||||
|
languageCode: IetfLanguageCode? = null
|
||||||
|
) = execute(SetMyName(name, languageCode))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setMyName(
|
||||||
|
name: String?,
|
||||||
|
languageCode: String?
|
||||||
|
) = setMyName(name, languageCode ?.let(::IetfLanguageCode))
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.edit
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.abstracts.TextedWithTextSources
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.edit.caption.editMessageCaption
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.edit.media.editMessageMedia
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.edit.text.editMessageText
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
|
import dev.inmo.tgbotapi.types.chat.Chat
|
||||||
|
import dev.inmo.tgbotapi.types.location.LiveLocation
|
||||||
|
import dev.inmo.tgbotapi.types.media.TelegramMedia
|
||||||
|
import dev.inmo.tgbotapi.types.message.ParseMode
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.textsources.TextSource
|
||||||
|
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
|
||||||
|
import dev.inmo.tgbotapi.utils.EntitiesBuilderBody
|
||||||
|
import dev.inmo.tgbotapi.utils.buildEntities
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
latitude: Double,
|
||||||
|
longitude: Double,
|
||||||
|
horizontalAccuracy: Meters? = null,
|
||||||
|
heading: Degrees? = null,
|
||||||
|
proximityAlertRadius: Meters? = null,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = editLiveLocation(messageId, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
location: LiveLocation,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = editLiveLocation(
|
||||||
|
messageId, location, replyMarkup
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
media: TelegramMedia,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = editMessageMedia(messageId, media, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = editMessageReplyMarkup(messageId, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
text: String,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableWebPagePreview: Boolean? = null,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = editMessageText(messageId, text, parseMode, disableWebPagePreview, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableWebPagePreview: Boolean? = null,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = editMessageText(messageId, entities, disableWebPagePreview, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
separator: TextSource? = null,
|
||||||
|
disableWebPagePreview: Boolean? = null,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null,
|
||||||
|
builderBody: EntitiesBuilderBody
|
||||||
|
) = edit(messageId, buildEntities(separator, builderBody), disableWebPagePreview, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.edit(
|
||||||
|
messageId: InlineMessageIdentifier,
|
||||||
|
separator: String,
|
||||||
|
disableWebPagePreview: Boolean? = null,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null,
|
||||||
|
builderBody: EntitiesBuilderBody
|
||||||
|
) = edit(messageId, buildEntities(separator, builderBody), disableWebPagePreview, replyMarkup)
|
||||||
@@ -10,6 +10,17 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
|||||||
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
* as a builder for that
|
* as a builder for that
|
||||||
*/
|
*/
|
||||||
|
suspend fun TelegramBot.editMessageMedia(
|
||||||
|
inlineMessageId: InlineMessageIdentifier,
|
||||||
|
media: TelegramMedia,
|
||||||
|
replyMarkup: InlineKeyboardMarkup? = null
|
||||||
|
) = execute(EditInlineMessageMedia(inlineMessageId, media, replyMarkup))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
|
||||||
|
* as a builder for that
|
||||||
|
*/
|
||||||
|
@Deprecated("Renamed", ReplaceWith("this.editMessageMedia(inlineMessageId, media, replyMarkup)", "dev.inmo.tgbotapi.extensions.api.edit.media.editMessageMedia"))
|
||||||
suspend fun TelegramBot.editMessageCaption(
|
suspend fun TelegramBot.editMessageCaption(
|
||||||
inlineMessageId: InlineMessageIdentifier,
|
inlineMessageId: InlineMessageIdentifier,
|
||||||
media: TelegramMedia,
|
media: TelegramMedia,
|
||||||
|
|||||||
@@ -10,117 +10,127 @@ import dev.inmo.tgbotapi.utils.RiskFeature
|
|||||||
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
|
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
|
|
||||||
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
||||||
|
|
||||||
@RiskFeature(lowLevelRiskFeatureMessage)
|
@RiskFeature(lowLevelRiskFeatureMessage)
|
||||||
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContent(
|
suspend inline fun BehaviourContext.waitContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
): Flow<O> = waitContentMessage<O>(initRequest, errorFactory).map { it.content }
|
): Flow<MessageContent> = waitContentMessage(initRequest, errorFactory).map { it.content }
|
||||||
|
|
||||||
|
inline fun <reified T : MessageContent> Flow<MessageContent>.mapContent() = mapNotNull { it as? T }
|
||||||
|
|
||||||
suspend fun BehaviourContext.waitAnyContent(
|
suspend fun BehaviourContext.waitAnyContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<MessageContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory)
|
||||||
|
suspend fun BehaviourContext.waitTextedContent(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitContent(initRequest, errorFactory).mapContent<TextedContent>()
|
||||||
suspend fun BehaviourContext.waitContact(
|
suspend fun BehaviourContext.waitContact(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<ContactContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<ContactContent>()
|
||||||
suspend fun BehaviourContext.waitDice(
|
suspend fun BehaviourContext.waitDice(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<DiceContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<DiceContent>()
|
||||||
suspend fun BehaviourContext.waitGame(
|
suspend fun BehaviourContext.waitGame(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<GameContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<GameContent>()
|
||||||
suspend fun BehaviourContext.waitLocation(
|
suspend fun BehaviourContext.waitLocation(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<LocationContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<LocationContent>()
|
||||||
suspend fun BehaviourContext.waitLiveLocation(
|
suspend fun BehaviourContext.waitLiveLocation(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<LiveLocationContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<LiveLocationContent>()
|
||||||
suspend fun BehaviourContext.waitStaticLocation(
|
suspend fun BehaviourContext.waitStaticLocation(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<StaticLocationContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<StaticLocationContent>()
|
||||||
suspend fun BehaviourContext.waitPoll(
|
suspend fun BehaviourContext.waitPoll(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<PollContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<PollContent>()
|
||||||
suspend fun BehaviourContext.waitText(
|
suspend fun BehaviourContext.waitText(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<TextContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<TextContent>()
|
||||||
suspend fun BehaviourContext.waitVenue(
|
suspend fun BehaviourContext.waitVenue(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<VenueContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<VenueContent>()
|
||||||
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<AudioMediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<DocumentMediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitMedia(
|
suspend fun BehaviourContext.waitMedia(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<MediaContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<MediaContent>()
|
||||||
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<MediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<MediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<VisualMediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitTextedMediaContent(
|
suspend fun BehaviourContext.waitTextedMediaContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<TextedMediaContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<TextedMediaContent>()
|
||||||
suspend fun BehaviourContext.waitAnimation(
|
suspend fun BehaviourContext.waitAnimation(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<AnimationContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<AnimationContent>()
|
||||||
suspend fun BehaviourContext.waitAudio(
|
suspend fun BehaviourContext.waitAudio(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<AudioContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<AudioContent>()
|
||||||
suspend fun BehaviourContext.waitDocument(
|
suspend fun BehaviourContext.waitDocument(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<DocumentContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<DocumentContent>()
|
||||||
suspend fun BehaviourContext.waitPhoto(
|
suspend fun BehaviourContext.waitPhoto(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContent<PhotoContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<PhotoContent>()
|
||||||
suspend fun BehaviourContext.waitSticker(
|
suspend fun BehaviourContext.waitSticker(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<StickerContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<StickerContent>()
|
||||||
suspend fun BehaviourContext.waitVideo(
|
suspend fun BehaviourContext.waitVideo(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<VideoContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<VideoContent>()
|
||||||
suspend fun BehaviourContext.waitVideoNote(
|
suspend fun BehaviourContext.waitVideoNote(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<VideoNoteContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<VideoNoteContent>()
|
||||||
suspend fun BehaviourContext.waitVoice(
|
suspend fun BehaviourContext.waitVoice(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<VoiceContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<VoiceContent>()
|
||||||
suspend fun BehaviourContext.waitInvoice(
|
suspend fun BehaviourContext.waitInvoice(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<InvoiceContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<InvoiceContent>()
|
||||||
suspend fun BehaviourContext.waitVisualContent(
|
suspend fun BehaviourContext.waitVisualContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContent(initRequest, errorFactory).mapContent<VisualMediaGroupPartContent>()
|
||||||
|
suspend fun BehaviourContext.waitMediaContent(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitContent(initRequest, errorFactory).mapContent<MediaContent>()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
|
|||||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||||
import dev.inmo.tgbotapi.extensions.utils.withContent
|
import dev.inmo.tgbotapi.extensions.utils.withContent
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.*
|
import dev.inmo.tgbotapi.types.message.content.*
|
||||||
@@ -12,142 +13,138 @@ import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
|||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
|
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
|
|
||||||
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
|
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
|
||||||
|
|
||||||
@RiskFeature(lowLevelRiskFeatureMessage)
|
@RiskFeature(lowLevelRiskFeatureMessage)
|
||||||
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContentMessage(
|
suspend inline fun BehaviourContext.waitContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
): Flow<CommonMessage<O>> = expectFlow(
|
): Flow<CommonMessage<MessageContent>> = expectFlow(
|
||||||
initRequest,
|
initRequest,
|
||||||
errorFactory
|
errorFactory
|
||||||
) {
|
) {
|
||||||
if (it !is BaseSentMessageUpdate) {
|
if (it !is BaseSentMessageUpdate) {
|
||||||
return@expectFlow emptyList()
|
return@expectFlow emptyList()
|
||||||
}
|
}
|
||||||
listOfNotNull((it.data as? CommonMessage<*>) ?.withContent<O>())
|
listOfNotNull((it.data as? CommonMessage<*>))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified T : MessageContent> contentMessageConverter(
|
inline fun <reified T : MessageContent> Flow<CommonMessage<MessageContent>>.mapWithContent() = mapNotNull { it.withContentOrNull<T>() }
|
||||||
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
|
|
||||||
): suspend CommonMessage<MessageContent>.() -> CommonMessage<T>? = mapper ?.let {
|
|
||||||
{
|
|
||||||
if (content is T) {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
val message = (this as CommonMessage<T>)
|
|
||||||
safelyWithoutExceptions { mapper(message) }
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} ?: {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
if (content is T) this as CommonMessage<T> else null
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun BehaviourContext.waitAnyContentMessage(
|
suspend fun BehaviourContext.waitAnyContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
) = waitContentMessage<MessageContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory)
|
||||||
|
suspend fun BehaviourContext.waitTextedContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedContent>()
|
||||||
suspend fun BehaviourContext.waitContactMessage(
|
suspend fun BehaviourContext.waitContactMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<ContactContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<ContactContent>()
|
||||||
suspend fun BehaviourContext.waitDiceMessage(
|
suspend fun BehaviourContext.waitDiceMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<DiceContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DiceContent>()
|
||||||
suspend fun BehaviourContext.waitGameMessage(
|
suspend fun BehaviourContext.waitGameMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<GameContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<GameContent>()
|
||||||
suspend fun BehaviourContext.waitLocationMessage(
|
suspend fun BehaviourContext.waitLocationMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<LocationContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<LocationContent>()
|
||||||
suspend fun BehaviourContext.waitLiveLocationMessage(
|
suspend fun BehaviourContext.waitLiveLocationMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<LiveLocationContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<LiveLocationContent>()
|
||||||
suspend fun BehaviourContext.waitStaticLocationMessage(
|
suspend fun BehaviourContext.waitStaticLocationMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<StaticLocationContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StaticLocationContent>()
|
||||||
suspend fun BehaviourContext.waitPollMessage(
|
suspend fun BehaviourContext.waitPollMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<PollContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<PollContent>()
|
||||||
suspend fun BehaviourContext.waitTextMessage(
|
suspend fun BehaviourContext.waitTextMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<TextContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextContent>()
|
||||||
suspend fun BehaviourContext.waitVenueMessage(
|
suspend fun BehaviourContext.waitVenueMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<VenueContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VenueContent>()
|
||||||
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
|
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AudioMediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
|
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DocumentMediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitMediaMessage(
|
suspend fun BehaviourContext.waitMediaMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<MediaContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaContent>()
|
||||||
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
|
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<MediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
|
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VisualMediaGroupPartContent>()
|
||||||
suspend fun BehaviourContext.waitTextedMediaContentMessage(
|
suspend fun BehaviourContext.waitTextedMediaContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<TextedMediaContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedMediaContent>()
|
||||||
suspend fun BehaviourContext.waitAnimationMessage(
|
suspend fun BehaviourContext.waitAnimationMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<AnimationContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AnimationContent>()
|
||||||
suspend fun BehaviourContext.waitAudioMessage(
|
suspend fun BehaviourContext.waitAudioMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<AudioContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AudioContent>()
|
||||||
suspend fun BehaviourContext.waitDocumentMessage(
|
suspend fun BehaviourContext.waitDocumentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<DocumentContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DocumentContent>()
|
||||||
suspend fun BehaviourContext.waitPhotoMessage(
|
suspend fun BehaviourContext.waitPhotoMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<PhotoContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<PhotoContent>()
|
||||||
suspend fun BehaviourContext.waitStickerMessage(
|
suspend fun BehaviourContext.waitStickerMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<StickerContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StickerContent>()
|
||||||
suspend fun BehaviourContext.waitVideoMessage(
|
suspend fun BehaviourContext.waitVideoMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<VideoContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VideoContent>()
|
||||||
suspend fun BehaviourContext.waitVideoNoteMessage(
|
suspend fun BehaviourContext.waitVideoNoteMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<VideoNoteContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VideoNoteContent>()
|
||||||
suspend fun BehaviourContext.waitVoiceMessage(
|
suspend fun BehaviourContext.waitVoiceMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<VoiceContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VoiceContent>()
|
||||||
suspend fun BehaviourContext.waitInvoiceMessage(
|
suspend fun BehaviourContext.waitInvoiceMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<InvoiceContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<InvoiceContent>()
|
||||||
|
|
||||||
suspend fun BehaviourContext.waitVisualContentMessage(
|
suspend fun BehaviourContext.waitVisualContentMessage(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VisualMediaGroupPartContent>()
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitMediaContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaContent>()
|
||||||
|
|||||||
@@ -21,3 +21,17 @@ suspend fun BehaviourContext.waitDeepLinks(
|
|||||||
.flattenCommandsWithParams().mapNotNull {
|
.flattenCommandsWithParams().mapNotNull {
|
||||||
it.first to (it.second.second.singleOrNull() ?.regularTextSourceOrNull() ?.source ?.removePrefix(" ") ?: return@mapNotNull null)
|
it.first to (it.second.second.singleOrNull() ?.regularTextSourceOrNull() ?.source ?.removePrefix(" ") ?: return@mapNotNull null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitDeepLinks(
|
||||||
|
regex: Regex,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
): Flow<Pair<CommonMessage<TextContent>, String>> = waitDeepLinks(initRequest, errorFactory).filter {
|
||||||
|
regex.matches(it.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitDeepLinks(
|
||||||
|
deepLink: String,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
): Flow<Pair<CommonMessage<TextContent>, String>> = waitDeepLinks(Regex("^$deepLink$"), initRequest, errorFactory)
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.whenMentionTextSource
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.whenTextMentionTextSource
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.Username
|
||||||
|
import dev.inmo.tgbotapi.types.chat.User
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextedContent
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check, that [TextedContent.textSources] contains:
|
||||||
|
*
|
||||||
|
* * Any [dev.inmo.tgbotapi.types.message.textsources.MentionTextSource] with [dev.inmo.tgbotapi.types.message.textsources.MentionTextSource.username]
|
||||||
|
* equal to [username]
|
||||||
|
* * Any [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource] with [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource.user]
|
||||||
|
* with the same [username]
|
||||||
|
*/
|
||||||
|
fun TextedContent.isWithMention(username: Username) = textSources.any {
|
||||||
|
it.whenMentionTextSource {
|
||||||
|
it.username == username
|
||||||
|
} ?: it.whenTextMentionTextSource {
|
||||||
|
it.user.username == username
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check, that [TextedContent.textSources] contains:
|
||||||
|
*
|
||||||
|
* * Any [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource] with [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource.user]
|
||||||
|
* with the same [userId]
|
||||||
|
*/
|
||||||
|
fun TextedContent.isWithTextMention(userId: UserId) = textSources.any {
|
||||||
|
it.whenTextMentionTextSource {
|
||||||
|
it.user.id == userId
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithMention] with [user] [Username] (is presented) or [isWithTextMention] with [user] [UserId] to determine
|
||||||
|
* user mentioning in [this] [CommonMessage]
|
||||||
|
*/
|
||||||
|
fun TextedContent.isWithMention(user: User): Boolean = user.username ?.let { username -> isWithMention(username) } == true || isWithTextMention(user.id)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithMention] passing [username] as argument to take only messages with [username] mentions or text mentions
|
||||||
|
*/
|
||||||
|
fun Flow<TextedContent>.filterMentions(username: Username) = filter {
|
||||||
|
it.isWithMention(username)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithTextMention] passing [userId] as argument to take only messages with [userId] text mentions
|
||||||
|
*/
|
||||||
|
fun Flow<TextedContent>.filterTextMentions(userId: UserId) = filter {
|
||||||
|
it.isWithTextMention(userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithMention] passing [user] as argument to take only messages with [user] mentions or text mentions
|
||||||
|
*/
|
||||||
|
fun Flow<TextedContent>.filterMentions(user: User) = filter {
|
||||||
|
it.isWithMention(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates cold [Flow] with the messages with [TextedContent] where [username] has been mentioned
|
||||||
|
*
|
||||||
|
* @see filterMentions
|
||||||
|
* @see filterTextMentions
|
||||||
|
*/
|
||||||
|
suspend fun BehaviourContext.waitContentWithMentions (
|
||||||
|
username: Username,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitContent(initRequest, errorFactory).mapContent<TextedContent>().filterMentions(username)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates cold [Flow] with the messages with [TextedContent] where [userId] has been mentioned with text
|
||||||
|
*
|
||||||
|
* @see filterTextMentions
|
||||||
|
* @see filterMentions
|
||||||
|
* @see dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource
|
||||||
|
*/
|
||||||
|
suspend fun BehaviourContext.waitContentWithTextMentions (
|
||||||
|
userId: UserId,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitTextedContent(initRequest, errorFactory).filterTextMentions(userId)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates cold [Flow] with the messages with [TextedContent] where [user] has been mentioned as text or mentioned
|
||||||
|
* with text
|
||||||
|
*
|
||||||
|
* @see filterMentions
|
||||||
|
* @see filterTextMentions
|
||||||
|
*/
|
||||||
|
suspend fun BehaviourContext.waitContentWithMentions (
|
||||||
|
user: User,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitTextedContent(initRequest, errorFactory).filterMentions(user)
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.whenMentionTextSource
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.whenTextMentionTextSource
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.Username
|
||||||
|
import dev.inmo.tgbotapi.types.chat.User
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextedContent
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
|
||||||
|
fun CommonMessage<TextedContent>.isWithMention(username: Username) = content.isWithMention(username)
|
||||||
|
|
||||||
|
fun CommonMessage<TextedContent>.isWithTextMention(userId: UserId) = content.isWithTextMention(userId)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithMention] with [user] [Username] (is presented) or [isWithTextMention] with [user] [UserId] to determine
|
||||||
|
* user mentioning in [this] [CommonMessage]
|
||||||
|
*/
|
||||||
|
fun CommonMessage<TextedContent>.isWithMention(user: User): Boolean = content.isWithMention(user)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithMention] passing [username] as argument to take only messages with [username] mentions or text mentions
|
||||||
|
*/
|
||||||
|
fun Flow<CommonMessage<TextedContent>>.filterMentionsMessages(username: Username) = filter {
|
||||||
|
it.isWithMention(username)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithTextMention] passing [userId] as argument to take only messages with [userId] text mentions
|
||||||
|
*/
|
||||||
|
fun Flow<CommonMessage<TextedContent>>.filterTextMentionsMessages(userId: UserId) = filter {
|
||||||
|
it.isWithTextMention(userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [isWithMention] passing [user] as argument to take only messages with [user] mentions or text mentions
|
||||||
|
*/
|
||||||
|
fun Flow<CommonMessage<TextedContent>>.filterMentionsMessages(user: User) = filter {
|
||||||
|
it.isWithMention(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates cold [Flow] with the messages with [TextedContent] where [username] has been mentioned
|
||||||
|
*
|
||||||
|
* @see filterMentions
|
||||||
|
* @see filterTextMentions
|
||||||
|
*/
|
||||||
|
suspend fun BehaviourContext.waitContentMessageWithMentions (
|
||||||
|
username: Username,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedContent>().filterMentionsMessages(username)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates cold [Flow] with the messages with [TextedContent] where [userId] has been mentioned with text
|
||||||
|
*
|
||||||
|
* @see filterTextMentions
|
||||||
|
* @see filterMentions
|
||||||
|
* @see dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource
|
||||||
|
*/
|
||||||
|
suspend fun BehaviourContext.waitContentMessageWithTextMentions (
|
||||||
|
userId: UserId,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitTextedContentMessage(initRequest, errorFactory).filterTextMentionsMessages(userId)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates cold [Flow] with the messages with [TextedContent] where [user] has been mentioned as text or mentioned
|
||||||
|
* with text
|
||||||
|
*
|
||||||
|
* @see filterMentions
|
||||||
|
* @see filterTextMentions
|
||||||
|
*/
|
||||||
|
suspend fun BehaviourContext.waitContentMessageWithMentions (
|
||||||
|
user: User,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitTextedContentMessage(initRequest, errorFactory).filterMentionsMessages(user)
|
||||||
@@ -248,6 +248,30 @@ suspend fun <BC : BehaviourContext> BC.onText(
|
|||||||
scenarioReceiver
|
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.onTextedContent(
|
||||||
|
initialFilter: CommonMessageFilter<TextedContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMessage, Update> = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in TextedMessage, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMessage>
|
||||||
|
) = onContentMessageWithType(
|
||||||
|
initialFilter,
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
* @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,
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
@@ -631,3 +655,27 @@ suspend fun <BC : BehaviourContext> BC.onVisualContent(
|
|||||||
markerFactory,
|
markerFactory,
|
||||||
scenarioReceiver
|
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.onMediaContent(
|
||||||
|
initialFilter: CommonMessageFilter<MediaContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
|
||||||
|
) = onContentMessageWithType(
|
||||||
|
initialFilter,
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|||||||
@@ -46,3 +46,24 @@ suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
|||||||
this@onDeepLink.launchSafelyWithoutExceptions { triggersHolder.handleableCommandsHolder.unregisterHandleable(startRegex) }
|
this@onDeepLink.launchSafelyWithoutExceptions { triggersHolder.handleableCommandsHolder.unregisterHandleable(startRegex) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
||||||
|
regex: Regex,
|
||||||
|
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) },
|
||||||
|
markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) },
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>>
|
||||||
|
): Job {
|
||||||
|
val internalFilter = SimpleFilter<Pair<TextMessage, String>> {
|
||||||
|
regex.matches(it.second)
|
||||||
|
}
|
||||||
|
return onDeepLink(initialFilter ?.let { internalFilter * it } ?: internalFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
||||||
|
deepLink: String,
|
||||||
|
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) },
|
||||||
|
markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) },
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>>
|
||||||
|
): Job = onDeepLink(Regex("^$deepLink$"), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|||||||
@@ -0,0 +1,357 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTwoTypesReceiver
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTypeReceiver
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.isWithMention
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.isWithTextMention
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.AnyMarkerFactory
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.Username
|
||||||
|
import dev.inmo.tgbotapi.types.chat.User
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.AnimationContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.AudioContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.DocumentContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.PhotoContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextedContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.VideoContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.VoiceContent
|
||||||
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
|
internal suspend inline fun <BC : BehaviourContext, reified T : TextedContent> BC.onMention(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<T>? = null,
|
||||||
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = AnyMarkerFactory(),
|
||||||
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
||||||
|
) = onContentMessageWithType<BC, T>(
|
||||||
|
initialFilter * {
|
||||||
|
it.content.isWithMention(username)
|
||||||
|
},
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|
||||||
|
internal suspend inline fun <BC : BehaviourContext, reified T : TextedContent> BC.onTextMention(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<T>? = null,
|
||||||
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = AnyMarkerFactory(),
|
||||||
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
||||||
|
) = onContentMessageWithType<BC, T>(
|
||||||
|
initialFilter * {
|
||||||
|
it.content.isWithTextMention(userId)
|
||||||
|
},
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|
||||||
|
internal suspend inline fun <BC : BehaviourContext, reified T : TextedContent> BC.onMention(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<T>? = null,
|
||||||
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = AnyMarkerFactory(),
|
||||||
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
||||||
|
) = onContentMessageWithType<BC, T>(
|
||||||
|
initialFilter * {
|
||||||
|
it.content.isWithMention(user)
|
||||||
|
},
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithAnyContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<TextedContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextedContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithAnyContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<TextedContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextedContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithAnyContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<TextedContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextedContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithVoiceContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<VoiceContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithVoiceContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<VoiceContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithVoiceContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<VoiceContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<MediaGroupContent<MediaGroupPartContent>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupContent<MediaGroupPartContent>>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithMediaGroupContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<MediaGroupContent<MediaGroupPartContent>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupContent<MediaGroupPartContent>>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<MediaGroupContent<MediaGroupPartContent>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupContent<MediaGroupPartContent>>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupPartContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<MediaGroupPartContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupPartContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupPartContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithMediaGroupPartContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<MediaGroupPartContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupPartContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupPartContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupPartContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<MediaGroupPartContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupPartContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupPartContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithAudioContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<AudioContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithAudioContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<AudioContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithAudioContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<AudioContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithDocumentContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<DocumentContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithDocumentContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<DocumentContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithDocumentContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<DocumentContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithVisualMediaGroupPartContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VisualMediaGroupPartContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VisualMediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VisualMediaGroupPartContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithVisualMediaGroupPartContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VisualMediaGroupPartContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VisualMediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VisualMediaGroupPartContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithVisualMediaGroupPartContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VisualMediaGroupPartContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VisualMediaGroupPartContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VisualMediaGroupPartContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithVideoContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<VideoContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithVideoContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<VideoContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithVideoContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<VideoContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithPhotoContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<PhotoContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithPhotoContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<PhotoContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithPhotoContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<PhotoContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithAnimationContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<AnimationContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithAnimationContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<AnimationContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithAnimationContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<AnimationContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithTextContent(
|
||||||
|
username: Username,
|
||||||
|
initialFilter: CommonMessageFilter<TextContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
||||||
|
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextMentionWithTextContent(
|
||||||
|
userId: UserId,
|
||||||
|
initialFilter: CommonMessageFilter<TextContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
||||||
|
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onMentionWithTextContent(
|
||||||
|
user: User,
|
||||||
|
initialFilter: CommonMessageFilter<TextContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update>? = null,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = AnyMarkerFactory(),
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
||||||
|
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ object ExceptionsOnlyLimiter : RequestLimiter {
|
|||||||
result = runCatchingSafely {
|
result = runCatchingSafely {
|
||||||
block()
|
block()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
it.printStackTrace()
|
|
||||||
if (it is TooMuchRequestsException) {
|
if (it is TooMuchRequestsException) {
|
||||||
delay(it.retryAfter.leftToRetry)
|
delay(it.retryAfter.leftToRetry)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ import kotlinx.serialization.encoding.Encoder
|
|||||||
* @see ByteArray.asMultipartFile
|
* @see ByteArray.asMultipartFile
|
||||||
* @see ByteReadChannel.asMultipartFile
|
* @see ByteReadChannel.asMultipartFile
|
||||||
* @see ByteReadChannelAllocator.asMultipartFile
|
* @see ByteReadChannelAllocator.asMultipartFile
|
||||||
|
*
|
||||||
|
* @see fromInput
|
||||||
|
* @see fromFile
|
||||||
|
* @see fromId
|
||||||
|
* @see fromUrl
|
||||||
*/
|
*/
|
||||||
@Serializable(InputFileSerializer::class)
|
@Serializable(InputFileSerializer::class)
|
||||||
sealed class InputFile {
|
sealed class InputFile {
|
||||||
@@ -29,9 +34,24 @@ sealed class InputFile {
|
|||||||
companion object {
|
companion object {
|
||||||
operator fun invoke(file: MPPFile) = file.asMultipartFile()
|
operator fun invoke(file: MPPFile) = file.asMultipartFile()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [MultipartFile] based on incoming [filename] and [inputSource]
|
||||||
|
*/
|
||||||
fun fromInput(filename: String, inputSource: () -> Input) = MultipartFile(filename, inputSource)
|
fun fromInput(filename: String, inputSource: () -> Input) = MultipartFile(filename, inputSource)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [MultipartFile] based on incoming [MPPFile] (common File in java, for example)
|
||||||
|
*/
|
||||||
fun fromFile(file: MPPFile) = invoke(file)
|
fun fromFile(file: MPPFile) = invoke(file)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [FileId] from the incomming [id] [String] with believe that it is [FileId]
|
||||||
|
*/
|
||||||
fun fromId(id: String) = FileId(id)
|
fun fromId(id: String) = FileId(id)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [FileUrl] from the incomming [url] [String]
|
||||||
|
*/
|
||||||
fun fromUrl(url: String) = FileUrl(url)
|
fun fromUrl(url: String) = FileUrl(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,30 @@ data class AnswerInlineQuery(
|
|||||||
val isPersonal: Boolean? = null,
|
val isPersonal: Boolean? = null,
|
||||||
@SerialName(nextOffsetField)
|
@SerialName(nextOffsetField)
|
||||||
val nextOffset: String? = null,
|
val nextOffset: String? = null,
|
||||||
@SerialName(switchPmTextField)
|
@SerialName(buttonField)
|
||||||
val switchPmText: String? = null,
|
val button: InlineQueryResultsButton? = null,
|
||||||
@SerialName(switchPmParameterField)
|
|
||||||
val switchPmParameter: String? = null
|
|
||||||
) : SimpleRequest<Boolean> {
|
) : SimpleRequest<Boolean> {
|
||||||
|
constructor(
|
||||||
|
inlineQueryID: InlineQueryIdentifier,
|
||||||
|
results: List<InlineQueryResult> = emptyList(),
|
||||||
|
cachedTime: Int? = null,
|
||||||
|
isPersonal: Boolean? = null,
|
||||||
|
nextOffset: String? = null,
|
||||||
|
switchPmText: String?,
|
||||||
|
switchPmParameter: String?
|
||||||
|
) : this(
|
||||||
|
inlineQueryID,
|
||||||
|
results,
|
||||||
|
cachedTime,
|
||||||
|
isPersonal,
|
||||||
|
nextOffset,
|
||||||
|
switchPmText ?.let {
|
||||||
|
switchPmParameter ?.let {
|
||||||
|
InlineQueryResultsButton.Start(switchPmText, switchPmParameter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
override fun method(): String = "answerInlineQuery"
|
override fun method(): String = "answerInlineQuery"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
get() = Boolean.serializer()
|
get() = Boolean.serializer()
|
||||||
@@ -40,8 +59,23 @@ fun InlineQuery.createAnswer(
|
|||||||
cachedTime: Int? = null,
|
cachedTime: Int? = null,
|
||||||
isPersonal: Boolean? = null,
|
isPersonal: Boolean? = null,
|
||||||
nextOffset: String? = null,
|
nextOffset: String? = null,
|
||||||
switchPmText: String? = null,
|
button: InlineQueryResultsButton? = null,
|
||||||
switchPmParameter: String? = null
|
) = AnswerInlineQuery(
|
||||||
|
id,
|
||||||
|
results,
|
||||||
|
cachedTime,
|
||||||
|
isPersonal,
|
||||||
|
nextOffset,
|
||||||
|
button
|
||||||
|
)
|
||||||
|
|
||||||
|
fun InlineQuery.createAnswer(
|
||||||
|
results: List<InlineQueryResult> = emptyList(),
|
||||||
|
cachedTime: Int? = null,
|
||||||
|
isPersonal: Boolean? = null,
|
||||||
|
nextOffset: String? = null,
|
||||||
|
switchPmText: String?,
|
||||||
|
switchPmParameter: String?
|
||||||
) = AnswerInlineQuery(
|
) = AnswerInlineQuery(
|
||||||
id,
|
id,
|
||||||
results,
|
results,
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.answers
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.common.Warning
|
||||||
|
import dev.inmo.tgbotapi.types.StartParameter
|
||||||
|
import dev.inmo.tgbotapi.types.startParameterField
|
||||||
|
import dev.inmo.tgbotapi.types.textField
|
||||||
|
import dev.inmo.tgbotapi.types.webAppField
|
||||||
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
|
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
|
@Serializable(InlineQueryResultsButtonSerializer::class)
|
||||||
|
@ClassCastsIncluded
|
||||||
|
sealed interface InlineQueryResultsButton {
|
||||||
|
val text: String
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class Raw internal constructor(
|
||||||
|
@SerialName(textField)
|
||||||
|
val text: String,
|
||||||
|
@SerialName(webAppField)
|
||||||
|
val webAppInfo: WebAppInfo? = null,
|
||||||
|
@SerialName(startParameterField)
|
||||||
|
val deepLinkParameter: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable(InlineQueryResultsButtonSerializer::class)
|
||||||
|
data class WebApp(
|
||||||
|
@SerialName(textField)
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(webAppField)
|
||||||
|
val webAppInfo: WebAppInfo
|
||||||
|
) : InlineQueryResultsButton
|
||||||
|
|
||||||
|
@Serializable(InlineQueryResultsButtonSerializer::class)
|
||||||
|
data class Start(
|
||||||
|
@SerialName(textField)
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(startParameterField)
|
||||||
|
val deepLinkParameter: String
|
||||||
|
) : InlineQueryResultsButton
|
||||||
|
|
||||||
|
@Serializable(InlineQueryResultsButtonSerializer::class)
|
||||||
|
data class Unknown internal constructor (
|
||||||
|
@SerialName(textField)
|
||||||
|
override val text: String
|
||||||
|
) : InlineQueryResultsButton
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
operator fun invoke(
|
||||||
|
text: String,
|
||||||
|
deepLinkParameter: String
|
||||||
|
) = Start(text, deepLinkParameter)
|
||||||
|
operator fun invoke(
|
||||||
|
text: String,
|
||||||
|
webAppInfo: WebAppInfo
|
||||||
|
) = WebApp(text, webAppInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object InlineQueryResultsButtonSerializer : KSerializer<InlineQueryResultsButton> {
|
||||||
|
override val descriptor: SerialDescriptor = InlineQueryResultsButton.Raw.serializer().descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): InlineQueryResultsButton {
|
||||||
|
val raw = InlineQueryResultsButton.Raw.serializer().deserialize(decoder)
|
||||||
|
|
||||||
|
return when {
|
||||||
|
raw.webAppInfo != null -> InlineQueryResultsButton.WebApp(raw.text, raw.webAppInfo)
|
||||||
|
raw.deepLinkParameter != null -> InlineQueryResultsButton.Start(raw.text, raw.deepLinkParameter)
|
||||||
|
else -> InlineQueryResultsButton.Unknown(raw.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: InlineQueryResultsButton) {
|
||||||
|
InlineQueryResultsButton.Raw.serializer().serialize(
|
||||||
|
encoder,
|
||||||
|
InlineQueryResultsButton.Raw(
|
||||||
|
value.text,
|
||||||
|
(value as? InlineQueryResultsButton.WebApp)?.webAppInfo,
|
||||||
|
(value as? InlineQueryResultsButton.Start)?.deepLinkParameter,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||||
|
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||||
|
import dev.inmo.tgbotapi.types.commands.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class GetMyName(
|
||||||
|
@SerialName(languageCodeField)
|
||||||
|
@Serializable(IetfLanguageCodeSerializer::class)
|
||||||
|
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||||
|
) : SimpleRequest<BotName>, WithOptionalLanguageCode {
|
||||||
|
override fun method(): String = "getMyName"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<BotName>
|
||||||
|
get() = BotName.serializer()
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||||
|
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||||
|
import dev.inmo.tgbotapi.types.commands.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class SetMyName(
|
||||||
|
@SerialName(nameField)
|
||||||
|
val name: String? = null,
|
||||||
|
@SerialName(languageCodeField)
|
||||||
|
@Serializable(IetfLanguageCodeSerializer::class)
|
||||||
|
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||||
|
) : SimpleRequest<Boolean>, WithOptionalLanguageCode {
|
||||||
|
override fun method(): String = "setMyName"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
get() = Boolean.serializer()
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package dev.inmo.tgbotapi.types
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BotName(
|
||||||
|
@SerialName(nameField)
|
||||||
|
val name: String
|
||||||
|
)
|
||||||
@@ -13,8 +13,9 @@ import kotlinx.serialization.json.JsonPrimitive
|
|||||||
import kotlinx.serialization.json.longOrNull
|
import kotlinx.serialization.json.longOrNull
|
||||||
import kotlin.jvm.JvmInline
|
import kotlin.jvm.JvmInline
|
||||||
|
|
||||||
|
const val internalTgAppLinksBeginning = "tg://"
|
||||||
const val internalLinkBeginning = "https://t.me"
|
const val internalLinkBeginning = "https://t.me"
|
||||||
const val internalUserLinkBeginning = "tg://user?id="
|
const val internalUserLinkBeginning = "${internalTgAppLinksBeginning}user?id="
|
||||||
|
|
||||||
@Serializable(ChatIdentifierSerializer::class)
|
@Serializable(ChatIdentifierSerializer::class)
|
||||||
@ClassCastsIncluded
|
@ClassCastsIncluded
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ typealias WebAppQueryId = String
|
|||||||
@JvmInline
|
@JvmInline
|
||||||
value class CustomEmojiId(
|
value class CustomEmojiId(
|
||||||
val string: String
|
val string: String
|
||||||
)
|
) {
|
||||||
|
val appLink
|
||||||
|
get() = "${internalTgAppLinksBeginning}emoji?id=$this"
|
||||||
|
}
|
||||||
|
|
||||||
typealias Seconds = Int
|
typealias Seconds = Int
|
||||||
typealias MilliSeconds = Long
|
typealias MilliSeconds = Long
|
||||||
@@ -247,10 +250,15 @@ const val errorMessageField = "error_message"
|
|||||||
const val messageTextField = "message_text"
|
const val messageTextField = "message_text"
|
||||||
const val isPersonalField = "is_personal"
|
const val isPersonalField = "is_personal"
|
||||||
const val nextOffsetField = "next_offset"
|
const val nextOffsetField = "next_offset"
|
||||||
|
const val buttonField = "button"
|
||||||
const val switchPmTextField = "switch_pm_text"
|
const val switchPmTextField = "switch_pm_text"
|
||||||
const val switchPmParameterField = "switch_pm_parameter"
|
const val switchPmParameterField = "switch_pm_parameter"
|
||||||
const val maxAllowedConnectionsField = "max_connections"
|
const val maxAllowedConnectionsField = "max_connections"
|
||||||
const val allowedUpdatesField = "allowed_updates"
|
const val allowedUpdatesField = "allowed_updates"
|
||||||
|
const val allowUserChatsField = "allow_user_chats"
|
||||||
|
const val allowBotChatsField = "allow_bot_chats"
|
||||||
|
const val allowGroupChatsField = "allow_group_chats"
|
||||||
|
const val allowChannelChatsField = "allow_channel_chats"
|
||||||
const val dropPendingUpdatesField = "drop_pending_updates"
|
const val dropPendingUpdatesField = "drop_pending_updates"
|
||||||
const val secretTokenField = "secret_token"
|
const val secretTokenField = "secret_token"
|
||||||
const val hasCustomCertificateField = "has_custom_certificate"
|
const val hasCustomCertificateField = "has_custom_certificate"
|
||||||
@@ -271,10 +279,12 @@ const val loginUrlField = "login_url"
|
|||||||
const val forwardTextField = "forward_text"
|
const val forwardTextField = "forward_text"
|
||||||
const val botUsernameField = "bot_username"
|
const val botUsernameField = "bot_username"
|
||||||
const val switchInlineQueryCurrentChatField = "switch_inline_query_current_chat"
|
const val switchInlineQueryCurrentChatField = "switch_inline_query_current_chat"
|
||||||
|
const val switchInlineQueryChosenChatField = "switch_inline_query_chosen_chat"
|
||||||
const val switchInlineQueryField = "switch_inline_query"
|
const val switchInlineQueryField = "switch_inline_query"
|
||||||
const val isAnimatedField = "is_animated"
|
const val isAnimatedField = "is_animated"
|
||||||
const val isVideoField = "is_video"
|
const val isVideoField = "is_video"
|
||||||
const val inviteLinkField = "invite_link"
|
const val inviteLinkField = "invite_link"
|
||||||
|
const val viaChatFolderInviteLinkField = "via_chat_folder_invite_link"
|
||||||
const val pinnedMessageField = "pinned_message"
|
const val pinnedMessageField = "pinned_message"
|
||||||
const val activeUsernamesField = "active_usernames"
|
const val activeUsernamesField = "active_usernames"
|
||||||
const val customTitleField = "custom_title"
|
const val customTitleField = "custom_title"
|
||||||
@@ -596,4 +606,5 @@ const val temporaryRegistrationField = "temporary_registration"
|
|||||||
|
|
||||||
const val buttonTextField = "button_text"
|
const val buttonTextField = "button_text"
|
||||||
const val webAppField = "web_app"
|
const val webAppField = "web_app"
|
||||||
|
const val webAppNameField = "web_app_name"
|
||||||
const val menuButtonField = "menu_button"
|
const val menuButtonField = "menu_button"
|
||||||
|
|||||||
@@ -11,9 +11,15 @@ const val UPDATE_SHIPPING_QUERY = "shipping_query"
|
|||||||
const val UPDATE_PRE_CHECKOUT_QUERY = "pre_checkout_query"
|
const val UPDATE_PRE_CHECKOUT_QUERY = "pre_checkout_query"
|
||||||
const val UPDATE_POLL = "poll"
|
const val UPDATE_POLL = "poll"
|
||||||
const val UPDATE_POLL_ANSWER = "poll_answer"
|
const val UPDATE_POLL_ANSWER = "poll_answer"
|
||||||
const val MY_CHAT_MEMBER = "my_chat_member"
|
const val UPDATE_MY_CHAT_MEMBER = "my_chat_member"
|
||||||
const val CHAT_MEMBER = "chat_member"
|
const val UPDATE_CHAT_MEMBER = "chat_member"
|
||||||
const val CHAT_JOIN_REQUEST = "chat_join_request"
|
const val UPDATE_CHAT_JOIN_REQUEST = "chat_join_request"
|
||||||
|
@Deprecated("Renamed", ReplaceWith("UPDATE_MY_CHAT_MEMBER", "dev.inmo.tgbotapi.types.UPDATE_MY_CHAT_MEMBER"))
|
||||||
|
const val MY_CHAT_MEMBER = UPDATE_MY_CHAT_MEMBER
|
||||||
|
@Deprecated("Renamed", ReplaceWith("UPDATE_CHAT_MEMBER", "dev.inmo.tgbotapi.types.UPDATE_CHAT_MEMBER"))
|
||||||
|
const val CHAT_MEMBER = UPDATE_CHAT_MEMBER
|
||||||
|
@Deprecated("Renamed", ReplaceWith("UPDATE_CHAT_JOIN_REQUEST", "dev.inmo.tgbotapi.types.UPDATE_CHAT_JOIN_REQUEST"))
|
||||||
|
const val CHAT_JOIN_REQUEST = UPDATE_CHAT_JOIN_REQUEST
|
||||||
|
|
||||||
val ALL_UPDATES_LIST = listOf(
|
val ALL_UPDATES_LIST = listOf(
|
||||||
UPDATE_MESSAGE,
|
UPDATE_MESSAGE,
|
||||||
@@ -27,7 +33,7 @@ val ALL_UPDATES_LIST = listOf(
|
|||||||
UPDATE_PRE_CHECKOUT_QUERY,
|
UPDATE_PRE_CHECKOUT_QUERY,
|
||||||
UPDATE_POLL,
|
UPDATE_POLL,
|
||||||
UPDATE_POLL_ANSWER,
|
UPDATE_POLL_ANSWER,
|
||||||
MY_CHAT_MEMBER,
|
UPDATE_MY_CHAT_MEMBER,
|
||||||
CHAT_MEMBER,
|
UPDATE_CHAT_MEMBER,
|
||||||
CHAT_JOIN_REQUEST
|
UPDATE_CHAT_JOIN_REQUEST
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -98,6 +98,23 @@ data class SwitchInlineQueryCurrentChatInlineKeyboardButton(
|
|||||||
val switchInlineQueryCurrentChat: String
|
val switchInlineQueryCurrentChat: String
|
||||||
) : InlineKeyboardButton
|
) : InlineKeyboardButton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complex button with [switchInlineQueryCurrentChat] which will be sent to you in an [dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery]
|
||||||
|
* which you may catch in [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onBaseInlineQuery] and get
|
||||||
|
* from [dev.inmo.tgbotapi.types.InlineQueries.query.BaseInlineQuery.query] (or changed by user query in case he will be
|
||||||
|
* the fastest hand in the wild west). Can be forwarded in any chat with message in case if it is the only one button in
|
||||||
|
* message, but will be converted to a [SwitchInlineQueryInlineKeyboardButton].
|
||||||
|
* Remember that clicking on this button will automatically insert username of this bot in current chat, paste
|
||||||
|
* [switchInlineQueryCurrentChat] as a query and create and inline request to your bot
|
||||||
|
* Visit https://core.telegram.org/bots/api#inlinekeyboardbutton for more info
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class SwitchInlineQueryChosenChatInlineKeyboardButton(
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(switchInlineQueryChosenChatField)
|
||||||
|
val parameters: SwitchInlineQueryChosenChat
|
||||||
|
) : InlineKeyboardButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complex button with [switchInlineQuery] which will be sent to you in an [dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery]
|
* Complex button with [switchInlineQuery] which will be sent to you in an [dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery]
|
||||||
* which you may catch in [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onBaseInlineQuery] and get
|
* which you may catch in [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onBaseInlineQuery] and get
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
|
|||||||
json[payField] != null -> PayInlineKeyboardButton.serializer()
|
json[payField] != null -> PayInlineKeyboardButton.serializer()
|
||||||
json[switchInlineQueryField] != null -> SwitchInlineQueryInlineKeyboardButton.serializer()
|
json[switchInlineQueryField] != null -> SwitchInlineQueryInlineKeyboardButton.serializer()
|
||||||
json[switchInlineQueryCurrentChatField] != null -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer()
|
json[switchInlineQueryCurrentChatField] != null -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer()
|
||||||
|
json[switchInlineQueryChosenChatField] != null -> SwitchInlineQueryChosenChatInlineKeyboardButton.serializer()
|
||||||
json[urlField] != null -> URLInlineKeyboardButton.serializer()
|
json[urlField] != null -> URLInlineKeyboardButton.serializer()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -47,6 +48,7 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
|
|||||||
is PayInlineKeyboardButton -> PayInlineKeyboardButton.serializer().serialize(encoder, value)
|
is PayInlineKeyboardButton -> PayInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value)
|
is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value)
|
is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
|
is SwitchInlineQueryChosenChatInlineKeyboardButton -> SwitchInlineQueryChosenChatInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is URLInlineKeyboardButton -> URLInlineKeyboardButton.serializer().serialize(encoder, value)
|
is URLInlineKeyboardButton -> URLInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is WebAppInlineKeyboardButton -> WebAppInlineKeyboardButton.serializer().serialize(encoder, value)
|
is WebAppInlineKeyboardButton -> WebAppInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value)
|
is CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.EncodeDefault
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
@Serializable
|
||||||
|
data class SwitchInlineQueryChosenChat (
|
||||||
|
@SerialName(queryField)
|
||||||
|
val query: String? = null,
|
||||||
|
@SerialName(allowUserChatsField)
|
||||||
|
@EncodeDefault
|
||||||
|
val allowUsers: Boolean = false,
|
||||||
|
@SerialName(allowBotChatsField)
|
||||||
|
@EncodeDefault
|
||||||
|
val allowBots: Boolean = false,
|
||||||
|
@SerialName(allowGroupChatsField)
|
||||||
|
@EncodeDefault
|
||||||
|
val allowGroups: Boolean = false,
|
||||||
|
@SerialName(allowChannelChatsField)
|
||||||
|
@EncodeDefault
|
||||||
|
val allowChannels: Boolean = false,
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
require(allowUsers || allowBots || allowGroups || allowChannels) {
|
||||||
|
"Bot must allow to choose at least one of available variants in choosing of inline query recipient"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,6 +57,52 @@ inline fun inlineQueryInCurrentChatInlineButton(
|
|||||||
data: String
|
data: String
|
||||||
) = SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data)
|
) = SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see inlineKeyboard
|
||||||
|
* @see InlineKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun inlineQueryInCurrentChatInlineButton(
|
||||||
|
text: String,
|
||||||
|
parameters: SwitchInlineQueryChosenChat
|
||||||
|
) = SwitchInlineQueryChosenChatInlineKeyboardButton(text, parameters)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see inlineKeyboard
|
||||||
|
* @see InlineKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun inlineQueryInCurrentChatInlineButton(
|
||||||
|
text: String,
|
||||||
|
query: String? = null,
|
||||||
|
allowUsers: Boolean = false,
|
||||||
|
allowBots: Boolean = false,
|
||||||
|
allowGroups: Boolean = false,
|
||||||
|
allowChannels: Boolean = false,
|
||||||
|
) = inlineQueryInCurrentChatInlineButton(
|
||||||
|
text,
|
||||||
|
SwitchInlineQueryChosenChat(
|
||||||
|
query = query,
|
||||||
|
allowUsers = allowUsers,
|
||||||
|
allowBots = allowBots,
|
||||||
|
allowGroups = allowGroups,
|
||||||
|
allowChannels = allowChannels
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see inlineKeyboard
|
||||||
|
* @see InlineKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun inlineQueryInAnyCurrentChatInlineButton(
|
||||||
|
text: String,
|
||||||
|
query: String? = null,
|
||||||
|
) = inlineQueryInCurrentChatInlineButton(text, query, allowUsers = true, allowBots = true, allowGroups = true, allowChannels = true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and put [SwitchInlineQueryInlineKeyboardButton]
|
* Creates and put [SwitchInlineQueryInlineKeyboardButton]
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -21,5 +21,7 @@ data class ChatMemberUpdated(
|
|||||||
@SerialName(newChatMemberField)
|
@SerialName(newChatMemberField)
|
||||||
val newChatMemberState: ChatMember,
|
val newChatMemberState: ChatMember,
|
||||||
@SerialName(inviteLinkField)
|
@SerialName(inviteLinkField)
|
||||||
val inviteLink: ChatInviteLink? = null
|
val inviteLink: ChatInviteLink? = null,
|
||||||
|
@SerialName(viaChatFolderInviteLinkField)
|
||||||
|
val viaChatFolderInviteLink: Boolean? = false
|
||||||
) : WithChat, WithUser
|
) : WithChat, WithUser
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ data class StickerSurrogate(
|
|||||||
val height: Int,
|
val height: Int,
|
||||||
val is_animated: Boolean? = null,
|
val is_animated: Boolean? = null,
|
||||||
val is_video: Boolean? = null,
|
val is_video: Boolean? = null,
|
||||||
val thumb: PhotoSize? = null,
|
val thumbnail: PhotoSize? = null,
|
||||||
val emoji: String? = null,
|
val emoji: String? = null,
|
||||||
val set_name: StickerSetName? = null,
|
val set_name: StickerSetName? = null,
|
||||||
val premium_animation: File? = null,
|
val premium_animation: File? = null,
|
||||||
@@ -43,6 +43,7 @@ sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile {
|
|||||||
get() = false
|
get() = false
|
||||||
val isVideo
|
val isVideo
|
||||||
get() = false
|
get() = false
|
||||||
|
val type: StickerType
|
||||||
|
|
||||||
fun asInputSticker(emojis: List<String> = emoji ?.let { listOf(it) } ?: error("Unable to create input sticker without emojis")): InputSticker
|
fun asInputSticker(emojis: List<String> = emoji ?.let { listOf(it) } ?: error("Unable to create input sticker without emojis")): InputSticker
|
||||||
}
|
}
|
||||||
@@ -62,7 +63,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.file_unique_id,
|
surrogate.file_unique_id,
|
||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.premium_animation,
|
surrogate.premium_animation,
|
||||||
@@ -73,7 +74,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.file_unique_id,
|
surrogate.file_unique_id,
|
||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.premium_animation,
|
surrogate.premium_animation,
|
||||||
@@ -84,7 +85,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.file_unique_id,
|
surrogate.file_unique_id,
|
||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.premium_animation,
|
surrogate.premium_animation,
|
||||||
@@ -98,7 +99,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.mask_position,
|
surrogate.mask_position,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size
|
surrogate.file_size
|
||||||
@@ -109,7 +110,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.mask_position,
|
surrogate.mask_position,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size
|
surrogate.file_size
|
||||||
@@ -120,7 +121,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.mask_position,
|
surrogate.mask_position,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size
|
surrogate.file_size
|
||||||
@@ -133,7 +134,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size,
|
surrogate.file_size,
|
||||||
@@ -145,7 +146,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size,
|
surrogate.file_size,
|
||||||
@@ -157,7 +158,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size,
|
surrogate.file_size,
|
||||||
@@ -169,7 +170,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.file_unique_id,
|
surrogate.file_unique_id,
|
||||||
surrogate.width,
|
surrogate.width,
|
||||||
surrogate.height,
|
surrogate.height,
|
||||||
surrogate.thumb,
|
surrogate.thumbnail,
|
||||||
surrogate.emoji,
|
surrogate.emoji,
|
||||||
surrogate.set_name,
|
surrogate.set_name,
|
||||||
surrogate.file_size,
|
surrogate.file_size,
|
||||||
@@ -178,13 +179,35 @@ object StickerSerializer : KSerializer<Sticker> {
|
|||||||
surrogate.is_video == true -> StickerFormat.Video
|
surrogate.is_video == true -> StickerFormat.Video
|
||||||
else -> StickerFormat.Static
|
else -> StickerFormat.Static
|
||||||
},
|
},
|
||||||
|
surrogate.type,
|
||||||
json
|
json
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, value: Sticker) {
|
override fun serialize(encoder: Encoder, value: Sticker) {
|
||||||
TODO("Not yet implemented")
|
with(value) {
|
||||||
|
StickerSurrogate.serializer().serialize(
|
||||||
|
encoder,
|
||||||
|
StickerSurrogate(
|
||||||
|
fileId,
|
||||||
|
fileUniqueId,
|
||||||
|
type,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
isAnimated,
|
||||||
|
isVideo,
|
||||||
|
thumbnail,
|
||||||
|
emoji,
|
||||||
|
stickerSetName,
|
||||||
|
(this as? RegularSticker) ?.premiumAnimationFile,
|
||||||
|
(this as? MaskSticker) ?.maskPosition,
|
||||||
|
(this as? CustomEmojiSticker) ?.customEmojiId,
|
||||||
|
fileSize,
|
||||||
|
(this as? CustomEmojiSticker) ?.needsRepainting ?: false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -210,6 +233,9 @@ sealed interface AnimatedSticker : Sticker {
|
|||||||
sealed interface RegularSticker : Sticker {
|
sealed interface RegularSticker : Sticker {
|
||||||
val premiumAnimationFile: File?
|
val premiumAnimationFile: File?
|
||||||
|
|
||||||
|
override val type: StickerType.Regular
|
||||||
|
get() = StickerType.Regular
|
||||||
|
|
||||||
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
|
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
|
||||||
fileId,
|
fileId,
|
||||||
emojis,
|
emojis,
|
||||||
@@ -241,6 +267,11 @@ data class RegularSimpleSticker(
|
|||||||
@SerialName(stickerFormatField)
|
@SerialName(stickerFormatField)
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
override val stickerFormat: StickerFormat = StickerFormat.Static
|
override val stickerFormat: StickerFormat = StickerFormat.Static
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.Regular
|
||||||
|
get() = StickerType.Regular
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -263,7 +294,13 @@ data class RegularAnimatedSticker(
|
|||||||
override val premiumAnimationFile: File? = null,
|
override val premiumAnimationFile: File? = null,
|
||||||
@SerialName(fileSizeField)
|
@SerialName(fileSizeField)
|
||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
) : RegularSticker, AnimatedSticker
|
) : RegularSticker, AnimatedSticker {
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.Regular
|
||||||
|
get() = StickerType.Regular
|
||||||
|
}
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RegularVideoSticker(
|
data class RegularVideoSticker(
|
||||||
@SerialName(fileIdField)
|
@SerialName(fileIdField)
|
||||||
@@ -284,13 +321,22 @@ data class RegularVideoSticker(
|
|||||||
override val premiumAnimationFile: File? = null,
|
override val premiumAnimationFile: File? = null,
|
||||||
@SerialName(fileSizeField)
|
@SerialName(fileSizeField)
|
||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
) : RegularSticker, VideoSticker
|
) : RegularSticker, VideoSticker {
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.Regular
|
||||||
|
get() = StickerType.Regular
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
sealed interface MaskSticker : Sticker {
|
sealed interface MaskSticker : Sticker {
|
||||||
val maskPosition: MaskPosition?
|
val maskPosition: MaskPosition?
|
||||||
|
|
||||||
|
override val type: StickerType.Mask
|
||||||
|
get() = StickerType.Mask
|
||||||
|
|
||||||
override fun asInputSticker(emojis: List<String>) = InputSticker.Mask(
|
override fun asInputSticker(emojis: List<String>) = InputSticker.Mask(
|
||||||
fileId,
|
fileId,
|
||||||
emojis,
|
emojis,
|
||||||
@@ -321,6 +367,12 @@ data class MaskSimpleSticker(
|
|||||||
@SerialName(stickerFormatField)
|
@SerialName(stickerFormatField)
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
override val stickerFormat: StickerFormat = StickerFormat.Static
|
override val stickerFormat: StickerFormat = StickerFormat.Static
|
||||||
|
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.Mask
|
||||||
|
get() = StickerType.Mask
|
||||||
}
|
}
|
||||||
@Serializable
|
@Serializable
|
||||||
data class MaskAnimatedSticker(
|
data class MaskAnimatedSticker(
|
||||||
@@ -342,7 +394,13 @@ data class MaskAnimatedSticker(
|
|||||||
override val stickerSetName: StickerSetName? = null,
|
override val stickerSetName: StickerSetName? = null,
|
||||||
@SerialName(fileSizeField)
|
@SerialName(fileSizeField)
|
||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
) : MaskSticker, AnimatedSticker
|
) : MaskSticker, AnimatedSticker {
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.Mask
|
||||||
|
get() = StickerType.Mask
|
||||||
|
}
|
||||||
@Serializable
|
@Serializable
|
||||||
data class MaskVideoSticker(
|
data class MaskVideoSticker(
|
||||||
@SerialName(fileIdField)
|
@SerialName(fileIdField)
|
||||||
@@ -363,13 +421,22 @@ data class MaskVideoSticker(
|
|||||||
override val stickerSetName: StickerSetName? = null,
|
override val stickerSetName: StickerSetName? = null,
|
||||||
@SerialName(fileSizeField)
|
@SerialName(fileSizeField)
|
||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
) : MaskSticker, VideoSticker
|
) : MaskSticker, VideoSticker {
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.Mask
|
||||||
|
get() = StickerType.Mask
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
sealed interface CustomEmojiSticker : Sticker {
|
sealed interface CustomEmojiSticker : Sticker {
|
||||||
val customEmojiId: CustomEmojiId
|
val customEmojiId: CustomEmojiId
|
||||||
val needsRepainting: Boolean
|
val needsRepainting: Boolean
|
||||||
|
|
||||||
|
override val type: StickerType.CustomEmoji
|
||||||
|
get() = StickerType.CustomEmoji
|
||||||
|
|
||||||
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.CustomEmoji(
|
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.CustomEmoji(
|
||||||
fileId,
|
fileId,
|
||||||
emojis,
|
emojis,
|
||||||
@@ -403,6 +470,12 @@ data class CustomEmojiSimpleSticker(
|
|||||||
@SerialName(stickerFormatField)
|
@SerialName(stickerFormatField)
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
override val stickerFormat: StickerFormat = StickerFormat.Static
|
override val stickerFormat: StickerFormat = StickerFormat.Static
|
||||||
|
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.CustomEmoji
|
||||||
|
get() = StickerType.CustomEmoji
|
||||||
}
|
}
|
||||||
@Serializable
|
@Serializable
|
||||||
data class CustomEmojiAnimatedSticker(
|
data class CustomEmojiAnimatedSticker(
|
||||||
@@ -426,7 +499,13 @@ data class CustomEmojiAnimatedSticker(
|
|||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
@SerialName(needsRepaintingField)
|
@SerialName(needsRepaintingField)
|
||||||
override val needsRepainting: Boolean = false,
|
override val needsRepainting: Boolean = false,
|
||||||
) : CustomEmojiSticker, AnimatedSticker
|
) : CustomEmojiSticker, AnimatedSticker {
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.CustomEmoji
|
||||||
|
get() = StickerType.CustomEmoji
|
||||||
|
}
|
||||||
@Serializable
|
@Serializable
|
||||||
data class CustomEmojiVideoSticker(
|
data class CustomEmojiVideoSticker(
|
||||||
@SerialName(fileIdField)
|
@SerialName(fileIdField)
|
||||||
@@ -449,7 +528,13 @@ data class CustomEmojiVideoSticker(
|
|||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
@SerialName(needsRepaintingField)
|
@SerialName(needsRepaintingField)
|
||||||
override val needsRepainting: Boolean = false,
|
override val needsRepainting: Boolean = false,
|
||||||
) : CustomEmojiSticker, VideoSticker
|
) : CustomEmojiSticker, VideoSticker {
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
@EncodeDefault
|
||||||
|
override val type: StickerType.CustomEmoji
|
||||||
|
get() = StickerType.CustomEmoji
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class UnknownSticker(
|
data class UnknownSticker(
|
||||||
@@ -471,6 +556,9 @@ data class UnknownSticker(
|
|||||||
override val fileSize: Long? = null,
|
override val fileSize: Long? = null,
|
||||||
@SerialName(stickerFormatField)
|
@SerialName(stickerFormatField)
|
||||||
override val stickerFormat: StickerFormat = StickerFormat.Static,
|
override val stickerFormat: StickerFormat = StickerFormat.Static,
|
||||||
|
@SerialName(stickerTypeField)
|
||||||
|
@Serializable(StickerType.Serializer::class)
|
||||||
|
override val type: StickerType = StickerType.Regular,
|
||||||
val raw: JsonElement
|
val raw: JsonElement
|
||||||
) : Sticker {
|
) : Sticker {
|
||||||
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
|
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
||||||
|
import dev.inmo.tgbotapi.types.webAppNameField
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
object WriteAccessAllowed : ForumEvent
|
data class WriteAccessAllowed(
|
||||||
|
@SerialName(webAppNameField)
|
||||||
|
val webAppName: String? = null
|
||||||
|
) : ForumEvent
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content
|
package dev.inmo.tgbotapi.types.message.content
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.abstracts.SpoilerableData
|
import dev.inmo.tgbotapi.abstracts.SpoilerableData
|
||||||
|
import dev.inmo.tgbotapi.abstracts.TextedInput
|
||||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
@@ -51,6 +52,18 @@ sealed interface MessageContent: ResendableContent {
|
|||||||
|
|
||||||
additionalBuilder()
|
additionalBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
polymorphic(TextedContent::class) {
|
||||||
|
subclass(TextContent::class)
|
||||||
|
subclass(VoiceContent::class)
|
||||||
|
subclass(MediaGroupContent::class)
|
||||||
|
subclass(AudioContent::class)
|
||||||
|
subclass(DocumentContent::class)
|
||||||
|
subclass(VideoContent::class)
|
||||||
|
subclass(PhotoContent::class)
|
||||||
|
subclass(AnimationContent::class)
|
||||||
|
}
|
||||||
|
|
||||||
polymorphic(MediaCollectionContent::class) {
|
polymorphic(MediaCollectionContent::class) {
|
||||||
subclass(PhotoContent::class)
|
subclass(PhotoContent::class)
|
||||||
|
|
||||||
@@ -115,6 +128,11 @@ sealed interface MediaCollectionContent<T: TelegramMediaFile>: MessageContent, M
|
|||||||
val mediaCollection: List<T>
|
val mediaCollection: List<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All the subtypes of this content will have [text] and [textSources] fields
|
||||||
|
*/
|
||||||
|
sealed interface TextedContent : MessageContent, TextedInput
|
||||||
|
|
||||||
sealed interface MediaContent: MessageContent {
|
sealed interface MediaContent: MessageContent {
|
||||||
val media: TelegramMediaFile
|
val media: TelegramMediaFile
|
||||||
fun asTelegramMedia(): TelegramMedia
|
fun asTelegramMedia(): TelegramMedia
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ sealed interface DocumentMediaGroupPartContent : MediaGroupPartContent {
|
|||||||
override fun toMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia
|
override fun toMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface TextedMediaContent : MediaContent, TextedInput
|
sealed interface TextedMediaContent : TextedContent, MediaContent
|
||||||
|
|
||||||
sealed interface MediaGroupCollectionContent<T : MediaGroupPartContent> : TextedMediaContent {
|
sealed interface MediaGroupCollectionContent<T : MediaGroupPartContent> : TextedMediaContent {
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import kotlinx.serialization.Serializable
|
|||||||
data class TextContent(
|
data class TextContent(
|
||||||
override val text: String,
|
override val text: String,
|
||||||
override val textSources: TextSourcesList = emptyList(),
|
override val textSources: TextSourcesList = emptyList(),
|
||||||
) : MessageContent, TextedInput {
|
) : TextedContent {
|
||||||
override fun createResend(
|
override fun createResend(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
messageThreadId: MessageThreadId?,
|
messageThreadId: MessageThreadId?,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package dev.inmo.tgbotapi.types.message.content
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
|
|
||||||
|
typealias TextedMessage = CommonMessage<TextedContent>
|
||||||
|
|
||||||
typealias InvoiceMessage = CommonMessage<InvoiceContent>
|
typealias InvoiceMessage = CommonMessage<InvoiceContent>
|
||||||
typealias VenueMessage = CommonMessage<VenueContent>
|
typealias VenueMessage = CommonMessage<VenueContent>
|
||||||
typealias GameMessage = CommonMessage<GameContent>
|
typealias GameMessage = CommonMessage<GameContent>
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ data class CustomEmojiTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
|
|||||||
override val subsources: TextSourcesList
|
override val subsources: TextSourcesList
|
||||||
) : MultilevelTextSource {
|
) : MultilevelTextSource {
|
||||||
override val markdown: String by lazy { source.customEmojiMarkdown() }
|
override val markdown: String by lazy { source.customEmojiMarkdown() }
|
||||||
override val markdownV2: String by lazy { source.customEmojiMarkdownV2() }
|
override val markdownV2: String by lazy { source.customEmojiMarkdownV2(customEmojiId) }
|
||||||
override val html: String by lazy { source.customEmojiHTML() }
|
override val html: String by lazy { source.customEmojiHTML(customEmojiId) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE")
|
@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE")
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const val htmlCodeControl = "code"
|
|||||||
const val htmlPreControl = "pre"
|
const val htmlPreControl = "pre"
|
||||||
const val htmlUnderlineControl = "u"
|
const val htmlUnderlineControl = "u"
|
||||||
const val htmlStrikethroughControl = "s"
|
const val htmlStrikethroughControl = "s"
|
||||||
|
const val htmlCustomEmojiControl = "tg-emoji"
|
||||||
|
|
||||||
private fun String.markdownDefault(
|
private fun String.markdownDefault(
|
||||||
openControlSymbol: String,
|
openControlSymbol: String,
|
||||||
@@ -120,8 +121,8 @@ internal fun String.commandMarkdownV2(): String = command(String::escapeMarkdown
|
|||||||
internal fun String.commandHTML(): String = command(String::toHtml)
|
internal fun String.commandHTML(): String = command(String::toHtml)
|
||||||
|
|
||||||
internal fun String.customEmojiMarkdown(): String = toMarkdown()
|
internal fun String.customEmojiMarkdown(): String = toMarkdown()
|
||||||
internal fun String.customEmojiMarkdownV2(): String = escapeMarkdownV2Common()
|
internal fun String.customEmojiMarkdownV2(customEmojiId: CustomEmojiId): String = "!${linkMarkdownV2(customEmojiId.appLink)}"
|
||||||
internal fun String.customEmojiHTML(): String = toHtml()
|
internal fun String.customEmojiHTML(customEmojiId: CustomEmojiId): String = "<$htmlCustomEmojiControl $htmlCustomEmojiControl=\"${customEmojiId.string}\">$this</$htmlCustomEmojiControl>"
|
||||||
|
|
||||||
internal fun String.regularMarkdown(): String = toMarkdown()
|
internal fun String.regularMarkdown(): String = toMarkdown()
|
||||||
internal fun String.regularMarkdownV2(): String = escapeMarkdownV2Common()
|
internal fun String.regularMarkdownV2(): String = escapeMarkdownV2Common()
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ package dev.inmo.tgbotapi.extensions.utils
|
|||||||
import dev.inmo.tgbotapi.abstracts.CommonSendInvoiceData
|
import dev.inmo.tgbotapi.abstracts.CommonSendInvoiceData
|
||||||
import dev.inmo.tgbotapi.abstracts.FromUser
|
import dev.inmo.tgbotapi.abstracts.FromUser
|
||||||
import dev.inmo.tgbotapi.abstracts.WithUser
|
import dev.inmo.tgbotapi.abstracts.WithUser
|
||||||
|
import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton
|
||||||
import dev.inmo.tgbotapi.requests.send.payments.CreateInvoiceLink
|
import dev.inmo.tgbotapi.requests.send.payments.CreateInvoiceLink
|
||||||
import dev.inmo.tgbotapi.requests.send.payments.SendInvoice
|
import dev.inmo.tgbotapi.requests.send.payments.SendInvoice
|
||||||
import dev.inmo.tgbotapi.requests.stickers.InputSticker
|
import dev.inmo.tgbotapi.requests.stickers.InputSticker
|
||||||
@@ -108,6 +109,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackGameInlineK
|
|||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.InlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.InlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.LoginURLInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.LoginURLInlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.PayInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.PayInlineKeyboardButton
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryChosenChatInlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryCurrentChatInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryCurrentChatInlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryInlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.URLInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.URLInlineKeyboardButton
|
||||||
@@ -327,6 +329,7 @@ import dev.inmo.tgbotapi.types.message.content.SpoilerableMediaContent
|
|||||||
import dev.inmo.tgbotapi.types.message.content.StaticLocationContent
|
import dev.inmo.tgbotapi.types.message.content.StaticLocationContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.StickerContent
|
import dev.inmo.tgbotapi.types.message.content.StickerContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextedContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.TextedMediaContent
|
import dev.inmo.tgbotapi.types.message.content.TextedMediaContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.VenueContent
|
import dev.inmo.tgbotapi.types.message.content.VenueContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.VideoContent
|
import dev.inmo.tgbotapi.types.message.content.VideoContent
|
||||||
@@ -1013,6 +1016,36 @@ public inline fun <T>
|
|||||||
WithUser.ifMessageGameShortNameCallbackQuery(block: (MessageGameShortNameCallbackQuery) -> T):
|
WithUser.ifMessageGameShortNameCallbackQuery(block: (MessageGameShortNameCallbackQuery) -> T):
|
||||||
T? = messageGameShortNameCallbackQueryOrNull() ?.let(block)
|
T? = messageGameShortNameCallbackQueryOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun InlineQueryResultsButton.startOrNull(): InlineQueryResultsButton.Start? = this as?
|
||||||
|
dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton.Start
|
||||||
|
|
||||||
|
public inline fun InlineQueryResultsButton.startOrThrow(): InlineQueryResultsButton.Start = this as
|
||||||
|
dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton.Start
|
||||||
|
|
||||||
|
public inline fun <T>
|
||||||
|
InlineQueryResultsButton.ifStart(block: (InlineQueryResultsButton.Start) -> T): T? =
|
||||||
|
startOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun InlineQueryResultsButton.unknownOrNull(): InlineQueryResultsButton.Unknown? = this
|
||||||
|
as? dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton.Unknown
|
||||||
|
|
||||||
|
public inline fun InlineQueryResultsButton.unknownOrThrow(): InlineQueryResultsButton.Unknown = this
|
||||||
|
as dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton.Unknown
|
||||||
|
|
||||||
|
public inline fun <T>
|
||||||
|
InlineQueryResultsButton.ifUnknown(block: (InlineQueryResultsButton.Unknown) -> T): T? =
|
||||||
|
unknownOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun InlineQueryResultsButton.webAppOrNull(): InlineQueryResultsButton.WebApp? = this
|
||||||
|
as? dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton.WebApp
|
||||||
|
|
||||||
|
public inline fun InlineQueryResultsButton.webAppOrThrow(): InlineQueryResultsButton.WebApp = this
|
||||||
|
as dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton.WebApp
|
||||||
|
|
||||||
|
public inline fun <T>
|
||||||
|
InlineQueryResultsButton.ifWebApp(block: (InlineQueryResultsButton.WebApp) -> T): T? =
|
||||||
|
webAppOrNull() ?.let(block)
|
||||||
|
|
||||||
public inline fun InputSticker.maskOrNull(): InputSticker.Mask? = this as?
|
public inline fun InputSticker.maskOrNull(): InputSticker.Mask? = this as?
|
||||||
dev.inmo.tgbotapi.requests.stickers.InputSticker.Mask
|
dev.inmo.tgbotapi.requests.stickers.InputSticker.Mask
|
||||||
|
|
||||||
@@ -1898,6 +1931,18 @@ public inline fun <T>
|
|||||||
InlineKeyboardButton.ifSwitchInlineQueryCurrentChatInlineKeyboardButton(block: (SwitchInlineQueryCurrentChatInlineKeyboardButton) -> T):
|
InlineKeyboardButton.ifSwitchInlineQueryCurrentChatInlineKeyboardButton(block: (SwitchInlineQueryCurrentChatInlineKeyboardButton) -> T):
|
||||||
T? = switchInlineQueryCurrentChatInlineKeyboardButtonOrNull() ?.let(block)
|
T? = switchInlineQueryCurrentChatInlineKeyboardButtonOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun InlineKeyboardButton.switchInlineQueryChosenChatInlineKeyboardButtonOrNull():
|
||||||
|
SwitchInlineQueryChosenChatInlineKeyboardButton? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryChosenChatInlineKeyboardButton
|
||||||
|
|
||||||
|
public inline fun InlineKeyboardButton.switchInlineQueryChosenChatInlineKeyboardButtonOrThrow():
|
||||||
|
SwitchInlineQueryChosenChatInlineKeyboardButton = this as
|
||||||
|
dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryChosenChatInlineKeyboardButton
|
||||||
|
|
||||||
|
public inline fun <T>
|
||||||
|
InlineKeyboardButton.ifSwitchInlineQueryChosenChatInlineKeyboardButton(block: (SwitchInlineQueryChosenChatInlineKeyboardButton) -> T):
|
||||||
|
T? = switchInlineQueryChosenChatInlineKeyboardButtonOrNull() ?.let(block)
|
||||||
|
|
||||||
public inline fun InlineKeyboardButton.switchInlineQueryInlineKeyboardButtonOrNull():
|
public inline fun InlineKeyboardButton.switchInlineQueryInlineKeyboardButtonOrNull():
|
||||||
SwitchInlineQueryInlineKeyboardButton? = this as?
|
SwitchInlineQueryInlineKeyboardButton? = this as?
|
||||||
dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryInlineKeyboardButton
|
dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryInlineKeyboardButton
|
||||||
@@ -3668,6 +3713,15 @@ public inline fun <T>
|
|||||||
ResendableContent.ifMediaCollectionContent(block: (MediaCollectionContent<TelegramMediaFile>) -> T):
|
ResendableContent.ifMediaCollectionContent(block: (MediaCollectionContent<TelegramMediaFile>) -> T):
|
||||||
T? = mediaCollectionContentOrNull() ?.let(block)
|
T? = mediaCollectionContentOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun ResendableContent.textedContentOrNull(): TextedContent? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.message.content.TextedContent
|
||||||
|
|
||||||
|
public inline fun ResendableContent.textedContentOrThrow(): TextedContent = this as
|
||||||
|
dev.inmo.tgbotapi.types.message.content.TextedContent
|
||||||
|
|
||||||
|
public inline fun <T> ResendableContent.ifTextedContent(block: (TextedContent) -> T): T? =
|
||||||
|
textedContentOrNull() ?.let(block)
|
||||||
|
|
||||||
public inline fun ResendableContent.mediaContentOrNull(): MediaContent? = this as?
|
public inline fun ResendableContent.mediaContentOrNull(): MediaContent? = this as?
|
||||||
dev.inmo.tgbotapi.types.message.content.MediaContent
|
dev.inmo.tgbotapi.types.message.content.MediaContent
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ fun makeLinkToMessage(
|
|||||||
username: Username,
|
username: Username,
|
||||||
messageId: MessageId,
|
messageId: MessageId,
|
||||||
threadId: MessageThreadId? = null
|
threadId: MessageThreadId? = null
|
||||||
): String = makeLinkToMessage(username.username, messageId, threadId)
|
): String = makeLinkToMessage(username.usernameWithoutAt, messageId, threadId)
|
||||||
fun makeLinkToMessage(
|
fun makeLinkToMessage(
|
||||||
chatId: Identifier,
|
chatId: Identifier,
|
||||||
messageId: MessageId,
|
messageId: MessageId,
|
||||||
|
|||||||
@@ -103,6 +103,45 @@ inline fun InlineKeyboardRowBuilder.inlineQueryInCurrentChatButton(
|
|||||||
data: String
|
data: String
|
||||||
) = add(SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data))
|
) = add(SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see inlineKeyboard
|
||||||
|
* @see InlineKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
|
||||||
|
text: String,
|
||||||
|
parameters: SwitchInlineQueryChosenChat
|
||||||
|
) = add(SwitchInlineQueryChosenChatInlineKeyboardButton(text, parameters))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see inlineKeyboard
|
||||||
|
* @see InlineKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
|
||||||
|
text: String,
|
||||||
|
query: String? = null,
|
||||||
|
allowUsers: Boolean = false,
|
||||||
|
allowBots: Boolean = false,
|
||||||
|
allowGroups: Boolean = false,
|
||||||
|
allowChannels: Boolean = false,
|
||||||
|
) = inlineQueryInChosenChatButton(
|
||||||
|
text,
|
||||||
|
SwitchInlineQueryChosenChat(
|
||||||
|
query = query,
|
||||||
|
allowUsers = allowUsers,
|
||||||
|
allowBots = allowBots,
|
||||||
|
allowGroups = allowGroups,
|
||||||
|
allowChannels = allowChannels
|
||||||
|
)
|
||||||
|
)
|
||||||
|
inline fun InlineKeyboardRowBuilder.inlineQueryInAnyChosenChatButton(
|
||||||
|
text: String,
|
||||||
|
query: String? = null,
|
||||||
|
) = inlineQueryInChosenChatButton(text, query, allowUsers = true, allowBots = true, allowGroups = true, allowChannels = true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and put [SwitchInlineQueryInlineKeyboardButton]
|
* Creates and put [SwitchInlineQueryInlineKeyboardButton]
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user