mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-16 12:00:18 +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
|
||||
|
||||
## 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
|
||||
|
||||
_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) |
|
||||
|:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
|
||||
| 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) |
|
||||
| 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) --->
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=7.0.2
|
||||
library_version=7.1.3
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[versions]
|
||||
|
||||
kotlin = "1.8.20"
|
||||
kotlin-serialization = "1.5.0"
|
||||
kotlin = "1.8.21"
|
||||
kotlin-serialization = "1.5.1"
|
||||
kotlin-coroutines = "1.6.4"
|
||||
|
||||
javax-activation = "1.1.1"
|
||||
@@ -10,10 +10,10 @@ korlibs = "3.4.0"
|
||||
uuid = "0.7.0"
|
||||
ktor = "2.3.0"
|
||||
|
||||
ksp = "1.8.20-1.0.11"
|
||||
kotlin-poet = "1.13.0"
|
||||
ksp = "1.8.21-1.0.11"
|
||||
kotlin-poet = "1.13.2"
|
||||
|
||||
microutils = "0.17.8"
|
||||
microutils = "0.18.4"
|
||||
|
||||
github-release-plugin = "2.4.1"
|
||||
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.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.query.InlineQuery
|
||||
import dev.inmo.tgbotapi.types.InlineQueryIdentifier
|
||||
@@ -12,8 +13,37 @@ suspend fun TelegramBot.answerInlineQuery(
|
||||
cachedTime: Int? = null,
|
||||
isPersonal: Boolean? = null,
|
||||
nextOffset: String? = null,
|
||||
switchPmText: String? = null,
|
||||
switchPmParameter: String? = null
|
||||
button: InlineQueryResultsButton? = 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(
|
||||
AnswerInlineQuery(inlineQueryID, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
||||
)
|
||||
@@ -24,8 +54,8 @@ suspend fun TelegramBot.answerInlineQuery(
|
||||
cachedTime: Int? = null,
|
||||
isPersonal: Boolean? = null,
|
||||
nextOffset: String? = null,
|
||||
switchPmText: String? = null,
|
||||
switchPmParameter: String? = null
|
||||
switchPmText: String?,
|
||||
switchPmParameter: String?
|
||||
) = answerInlineQuery(inlineQuery.id, results, cachedTime, isPersonal, nextOffset, switchPmText, switchPmParameter)
|
||||
|
||||
suspend fun TelegramBot.answer(
|
||||
@@ -34,6 +64,6 @@ suspend fun TelegramBot.answer(
|
||||
cachedTime: Int? = null,
|
||||
isPersonal: Boolean? = null,
|
||||
nextOffset: String? = null,
|
||||
switchPmText: String? = null,
|
||||
switchPmParameter: String? = null
|
||||
switchPmText: String?,
|
||||
switchPmParameter: String?
|
||||
) = 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]
|
||||
* 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(
|
||||
inlineMessageId: InlineMessageIdentifier,
|
||||
media: TelegramMedia,
|
||||
|
||||
@@ -10,117 +10,127 @@ import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
||||
|
||||
@RiskFeature(lowLevelRiskFeatureMessage)
|
||||
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContent(
|
||||
suspend inline fun BehaviourContext.waitContent(
|
||||
initRequest: Request<*>? = 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(
|
||||
initRequest: Request<*>? = 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(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<ContactContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<ContactContent>()
|
||||
suspend fun BehaviourContext.waitDice(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<DiceContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<DiceContent>()
|
||||
suspend fun BehaviourContext.waitGame(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<GameContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<GameContent>()
|
||||
suspend fun BehaviourContext.waitLocation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<LocationContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<LocationContent>()
|
||||
suspend fun BehaviourContext.waitLiveLocation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<LiveLocationContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<LiveLocationContent>()
|
||||
suspend fun BehaviourContext.waitStaticLocation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<StaticLocationContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<StaticLocationContent>()
|
||||
suspend fun BehaviourContext.waitPoll(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<PollContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<PollContent>()
|
||||
suspend fun BehaviourContext.waitText(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<TextContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<TextContent>()
|
||||
suspend fun BehaviourContext.waitVenue(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VenueContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<VenueContent>()
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<AudioMediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<DocumentMediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitMedia(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<MediaContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<MediaContent>()
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<MediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<MediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<VisualMediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitTextedMediaContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<TextedMediaContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<TextedMediaContent>()
|
||||
suspend fun BehaviourContext.waitAnimation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<AnimationContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<AnimationContent>()
|
||||
suspend fun BehaviourContext.waitAudio(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<AudioContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<AudioContent>()
|
||||
suspend fun BehaviourContext.waitDocument(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<DocumentContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<DocumentContent>()
|
||||
suspend fun BehaviourContext.waitPhoto(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<PhotoContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<PhotoContent>()
|
||||
suspend fun BehaviourContext.waitSticker(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<StickerContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<StickerContent>()
|
||||
suspend fun BehaviourContext.waitVideo(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VideoContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<VideoContent>()
|
||||
suspend fun BehaviourContext.waitVideoNote(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VideoNoteContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<VideoNoteContent>()
|
||||
suspend fun BehaviourContext.waitVoice(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VoiceContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<VoiceContent>()
|
||||
suspend fun BehaviourContext.waitInvoice(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<InvoiceContent>(initRequest, errorFactory)
|
||||
) = waitContent(initRequest, errorFactory).mapContent<InvoiceContent>()
|
||||
suspend fun BehaviourContext.waitVisualContent(
|
||||
initRequest: Request<*>? = 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.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||
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.types.message.abstracts.CommonMessage
|
||||
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.lowLevelRiskFeatureMessage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
|
||||
|
||||
@RiskFeature(lowLevelRiskFeatureMessage)
|
||||
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContentMessage(
|
||||
suspend inline fun BehaviourContext.waitContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
||||
): Flow<CommonMessage<O>> = expectFlow(
|
||||
): Flow<CommonMessage<MessageContent>> = expectFlow(
|
||||
initRequest,
|
||||
errorFactory
|
||||
) {
|
||||
if (it !is BaseSentMessageUpdate) {
|
||||
return@expectFlow emptyList()
|
||||
}
|
||||
listOfNotNull((it.data as? CommonMessage<*>) ?.withContent<O>())
|
||||
listOfNotNull((it.data as? CommonMessage<*>))
|
||||
}
|
||||
|
||||
internal inline fun <reified T : MessageContent> contentMessageConverter(
|
||||
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
|
||||
}
|
||||
inline fun <reified T : MessageContent> Flow<CommonMessage<MessageContent>>.mapWithContent() = mapNotNull { it.withContentOrNull<T>() }
|
||||
|
||||
suspend fun BehaviourContext.waitAnyContentMessage(
|
||||
initRequest: Request<*>? = 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(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<ContactContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<ContactContent>()
|
||||
suspend fun BehaviourContext.waitDiceMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<DiceContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DiceContent>()
|
||||
suspend fun BehaviourContext.waitGameMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<GameContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<GameContent>()
|
||||
suspend fun BehaviourContext.waitLocationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<LocationContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<LocationContent>()
|
||||
suspend fun BehaviourContext.waitLiveLocationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<LiveLocationContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<LiveLocationContent>()
|
||||
suspend fun BehaviourContext.waitStaticLocationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<StaticLocationContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StaticLocationContent>()
|
||||
suspend fun BehaviourContext.waitPollMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<PollContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<PollContent>()
|
||||
suspend fun BehaviourContext.waitTextMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<TextContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextContent>()
|
||||
suspend fun BehaviourContext.waitVenueMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VenueContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VenueContent>()
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AudioMediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DocumentMediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitMediaMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<MediaContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaContent>()
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<MediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VisualMediaGroupPartContent>()
|
||||
suspend fun BehaviourContext.waitTextedMediaContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<TextedMediaContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedMediaContent>()
|
||||
suspend fun BehaviourContext.waitAnimationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<AnimationContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AnimationContent>()
|
||||
suspend fun BehaviourContext.waitAudioMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<AudioContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AudioContent>()
|
||||
suspend fun BehaviourContext.waitDocumentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<DocumentContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DocumentContent>()
|
||||
suspend fun BehaviourContext.waitPhotoMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<PhotoContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<PhotoContent>()
|
||||
suspend fun BehaviourContext.waitStickerMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<StickerContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StickerContent>()
|
||||
suspend fun BehaviourContext.waitVideoMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VideoContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VideoContent>()
|
||||
suspend fun BehaviourContext.waitVideoNoteMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VideoNoteContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VideoNoteContent>()
|
||||
suspend fun BehaviourContext.waitVoiceMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VoiceContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VoiceContent>()
|
||||
suspend fun BehaviourContext.waitInvoiceMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<InvoiceContent>(initRequest, errorFactory)
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<InvoiceContent>()
|
||||
|
||||
suspend fun BehaviourContext.waitVisualContentMessage(
|
||||
initRequest: Request<*>? = 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 {
|
||||
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
|
||||
)
|
||||
|
||||
/**
|
||||
* @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 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,
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
block()
|
||||
}.onFailure {
|
||||
it.printStackTrace()
|
||||
if (it is TooMuchRequestsException) {
|
||||
delay(it.retryAfter.leftToRetry)
|
||||
} else {
|
||||
|
||||
@@ -21,6 +21,11 @@ import kotlinx.serialization.encoding.Encoder
|
||||
* @see ByteArray.asMultipartFile
|
||||
* @see ByteReadChannel.asMultipartFile
|
||||
* @see ByteReadChannelAllocator.asMultipartFile
|
||||
*
|
||||
* @see fromInput
|
||||
* @see fromFile
|
||||
* @see fromId
|
||||
* @see fromUrl
|
||||
*/
|
||||
@Serializable(InputFileSerializer::class)
|
||||
sealed class InputFile {
|
||||
@@ -29,9 +34,24 @@ sealed class InputFile {
|
||||
companion object {
|
||||
operator fun invoke(file: MPPFile) = file.asMultipartFile()
|
||||
|
||||
/**
|
||||
* Creates [MultipartFile] based on incoming [filename] and [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)
|
||||
|
||||
/**
|
||||
* Creates [FileId] from the incomming [id] [String] with believe that it is [FileId]
|
||||
*/
|
||||
fun fromId(id: String) = FileId(id)
|
||||
|
||||
/**
|
||||
* Creates [FileUrl] from the incomming [url] [String]
|
||||
*/
|
||||
fun fromUrl(url: String) = FileUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,30 @@ data class AnswerInlineQuery(
|
||||
val isPersonal: Boolean? = null,
|
||||
@SerialName(nextOffsetField)
|
||||
val nextOffset: String? = null,
|
||||
@SerialName(switchPmTextField)
|
||||
val switchPmText: String? = null,
|
||||
@SerialName(switchPmParameterField)
|
||||
val switchPmParameter: String? = null
|
||||
@SerialName(buttonField)
|
||||
val button: InlineQueryResultsButton? = null,
|
||||
) : 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 val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
get() = Boolean.serializer()
|
||||
@@ -40,8 +59,23 @@ fun InlineQuery.createAnswer(
|
||||
cachedTime: Int? = null,
|
||||
isPersonal: Boolean? = null,
|
||||
nextOffset: String? = null,
|
||||
switchPmText: String? = null,
|
||||
switchPmParameter: String? = null
|
||||
button: InlineQueryResultsButton? = 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(
|
||||
id,
|
||||
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 kotlin.jvm.JvmInline
|
||||
|
||||
const val internalTgAppLinksBeginning = "tg://"
|
||||
const val internalLinkBeginning = "https://t.me"
|
||||
const val internalUserLinkBeginning = "tg://user?id="
|
||||
const val internalUserLinkBeginning = "${internalTgAppLinksBeginning}user?id="
|
||||
|
||||
@Serializable(ChatIdentifierSerializer::class)
|
||||
@ClassCastsIncluded
|
||||
|
||||
@@ -41,7 +41,10 @@ typealias WebAppQueryId = String
|
||||
@JvmInline
|
||||
value class CustomEmojiId(
|
||||
val string: String
|
||||
)
|
||||
) {
|
||||
val appLink
|
||||
get() = "${internalTgAppLinksBeginning}emoji?id=$this"
|
||||
}
|
||||
|
||||
typealias Seconds = Int
|
||||
typealias MilliSeconds = Long
|
||||
@@ -247,10 +250,15 @@ const val errorMessageField = "error_message"
|
||||
const val messageTextField = "message_text"
|
||||
const val isPersonalField = "is_personal"
|
||||
const val nextOffsetField = "next_offset"
|
||||
const val buttonField = "button"
|
||||
const val switchPmTextField = "switch_pm_text"
|
||||
const val switchPmParameterField = "switch_pm_parameter"
|
||||
const val maxAllowedConnectionsField = "max_connections"
|
||||
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 secretTokenField = "secret_token"
|
||||
const val hasCustomCertificateField = "has_custom_certificate"
|
||||
@@ -271,10 +279,12 @@ const val loginUrlField = "login_url"
|
||||
const val forwardTextField = "forward_text"
|
||||
const val botUsernameField = "bot_username"
|
||||
const val switchInlineQueryCurrentChatField = "switch_inline_query_current_chat"
|
||||
const val switchInlineQueryChosenChatField = "switch_inline_query_chosen_chat"
|
||||
const val switchInlineQueryField = "switch_inline_query"
|
||||
const val isAnimatedField = "is_animated"
|
||||
const val isVideoField = "is_video"
|
||||
const val inviteLinkField = "invite_link"
|
||||
const val viaChatFolderInviteLinkField = "via_chat_folder_invite_link"
|
||||
const val pinnedMessageField = "pinned_message"
|
||||
const val activeUsernamesField = "active_usernames"
|
||||
const val customTitleField = "custom_title"
|
||||
@@ -596,4 +606,5 @@ const val temporaryRegistrationField = "temporary_registration"
|
||||
|
||||
const val buttonTextField = "button_text"
|
||||
const val webAppField = "web_app"
|
||||
const val webAppNameField = "web_app_name"
|
||||
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_POLL = "poll"
|
||||
const val UPDATE_POLL_ANSWER = "poll_answer"
|
||||
const val MY_CHAT_MEMBER = "my_chat_member"
|
||||
const val CHAT_MEMBER = "chat_member"
|
||||
const val CHAT_JOIN_REQUEST = "chat_join_request"
|
||||
const val UPDATE_MY_CHAT_MEMBER = "my_chat_member"
|
||||
const val UPDATE_CHAT_MEMBER = "chat_member"
|
||||
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(
|
||||
UPDATE_MESSAGE,
|
||||
@@ -27,7 +33,7 @@ val ALL_UPDATES_LIST = listOf(
|
||||
UPDATE_PRE_CHECKOUT_QUERY,
|
||||
UPDATE_POLL,
|
||||
UPDATE_POLL_ANSWER,
|
||||
MY_CHAT_MEMBER,
|
||||
CHAT_MEMBER,
|
||||
CHAT_JOIN_REQUEST
|
||||
UPDATE_MY_CHAT_MEMBER,
|
||||
UPDATE_CHAT_MEMBER,
|
||||
UPDATE_CHAT_JOIN_REQUEST
|
||||
)
|
||||
|
||||
@@ -98,6 +98,23 @@ data class SwitchInlineQueryCurrentChatInlineKeyboardButton(
|
||||
val switchInlineQueryCurrentChat: String
|
||||
) : 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]
|
||||
* 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[switchInlineQueryField] != null -> SwitchInlineQueryInlineKeyboardButton.serializer()
|
||||
json[switchInlineQueryCurrentChatField] != null -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer()
|
||||
json[switchInlineQueryChosenChatField] != null -> SwitchInlineQueryChosenChatInlineKeyboardButton.serializer()
|
||||
json[urlField] != null -> URLInlineKeyboardButton.serializer()
|
||||
else -> null
|
||||
}
|
||||
@@ -47,6 +48,7 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
|
||||
is PayInlineKeyboardButton -> PayInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||
is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.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 WebAppInlineKeyboardButton -> WebAppInlineKeyboardButton.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
|
||||
) = 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]
|
||||
*
|
||||
|
||||
@@ -21,5 +21,7 @@ data class ChatMemberUpdated(
|
||||
@SerialName(newChatMemberField)
|
||||
val newChatMemberState: ChatMember,
|
||||
@SerialName(inviteLinkField)
|
||||
val inviteLink: ChatInviteLink? = null
|
||||
val inviteLink: ChatInviteLink? = null,
|
||||
@SerialName(viaChatFolderInviteLinkField)
|
||||
val viaChatFolderInviteLink: Boolean? = false
|
||||
) : WithChat, WithUser
|
||||
|
||||
@@ -22,7 +22,7 @@ data class StickerSurrogate(
|
||||
val height: Int,
|
||||
val is_animated: Boolean? = null,
|
||||
val is_video: Boolean? = null,
|
||||
val thumb: PhotoSize? = null,
|
||||
val thumbnail: PhotoSize? = null,
|
||||
val emoji: String? = null,
|
||||
val set_name: StickerSetName? = null,
|
||||
val premium_animation: File? = null,
|
||||
@@ -43,6 +43,7 @@ sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile {
|
||||
get() = false
|
||||
val isVideo
|
||||
get() = false
|
||||
val type: StickerType
|
||||
|
||||
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.width,
|
||||
surrogate.height,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.premium_animation,
|
||||
@@ -73,7 +74,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.file_unique_id,
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.premium_animation,
|
||||
@@ -84,7 +85,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.file_unique_id,
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.premium_animation,
|
||||
@@ -98,7 +99,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.mask_position,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size
|
||||
@@ -109,7 +110,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.mask_position,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size
|
||||
@@ -120,7 +121,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.mask_position,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size
|
||||
@@ -133,7 +134,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size,
|
||||
@@ -145,7 +146,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size,
|
||||
@@ -157,7 +158,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size,
|
||||
@@ -169,7 +170,7 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.file_unique_id,
|
||||
surrogate.width,
|
||||
surrogate.height,
|
||||
surrogate.thumb,
|
||||
surrogate.thumbnail,
|
||||
surrogate.emoji,
|
||||
surrogate.set_name,
|
||||
surrogate.file_size,
|
||||
@@ -178,13 +179,35 @@ object StickerSerializer : KSerializer<Sticker> {
|
||||
surrogate.is_video == true -> StickerFormat.Video
|
||||
else -> StickerFormat.Static
|
||||
},
|
||||
surrogate.type,
|
||||
json
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
val premiumAnimationFile: File?
|
||||
|
||||
override val type: StickerType.Regular
|
||||
get() = StickerType.Regular
|
||||
|
||||
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
|
||||
fileId,
|
||||
emojis,
|
||||
@@ -241,6 +267,11 @@ data class RegularSimpleSticker(
|
||||
@SerialName(stickerFormatField)
|
||||
@EncodeDefault
|
||||
override val stickerFormat: StickerFormat = StickerFormat.Static
|
||||
@SerialName(stickerTypeField)
|
||||
@Serializable(StickerType.Serializer::class)
|
||||
@EncodeDefault
|
||||
override val type: StickerType.Regular
|
||||
get() = StickerType.Regular
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -263,7 +294,13 @@ data class RegularAnimatedSticker(
|
||||
override val premiumAnimationFile: File? = null,
|
||||
@SerialName(fileSizeField)
|
||||
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
|
||||
data class RegularVideoSticker(
|
||||
@SerialName(fileIdField)
|
||||
@@ -284,13 +321,22 @@ data class RegularVideoSticker(
|
||||
override val premiumAnimationFile: File? = null,
|
||||
@SerialName(fileSizeField)
|
||||
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
|
||||
sealed interface MaskSticker : Sticker {
|
||||
val maskPosition: MaskPosition?
|
||||
|
||||
override val type: StickerType.Mask
|
||||
get() = StickerType.Mask
|
||||
|
||||
override fun asInputSticker(emojis: List<String>) = InputSticker.Mask(
|
||||
fileId,
|
||||
emojis,
|
||||
@@ -321,6 +367,12 @@ data class MaskSimpleSticker(
|
||||
@SerialName(stickerFormatField)
|
||||
@EncodeDefault
|
||||
override val stickerFormat: StickerFormat = StickerFormat.Static
|
||||
|
||||
@SerialName(stickerTypeField)
|
||||
@Serializable(StickerType.Serializer::class)
|
||||
@EncodeDefault
|
||||
override val type: StickerType.Mask
|
||||
get() = StickerType.Mask
|
||||
}
|
||||
@Serializable
|
||||
data class MaskAnimatedSticker(
|
||||
@@ -342,7 +394,13 @@ data class MaskAnimatedSticker(
|
||||
override val stickerSetName: StickerSetName? = null,
|
||||
@SerialName(fileSizeField)
|
||||
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
|
||||
data class MaskVideoSticker(
|
||||
@SerialName(fileIdField)
|
||||
@@ -363,13 +421,22 @@ data class MaskVideoSticker(
|
||||
override val stickerSetName: StickerSetName? = null,
|
||||
@SerialName(fileSizeField)
|
||||
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
|
||||
sealed interface CustomEmojiSticker : Sticker {
|
||||
val customEmojiId: CustomEmojiId
|
||||
val needsRepainting: Boolean
|
||||
|
||||
override val type: StickerType.CustomEmoji
|
||||
get() = StickerType.CustomEmoji
|
||||
|
||||
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.CustomEmoji(
|
||||
fileId,
|
||||
emojis,
|
||||
@@ -403,6 +470,12 @@ data class CustomEmojiSimpleSticker(
|
||||
@SerialName(stickerFormatField)
|
||||
@EncodeDefault
|
||||
override val stickerFormat: StickerFormat = StickerFormat.Static
|
||||
|
||||
@SerialName(stickerTypeField)
|
||||
@Serializable(StickerType.Serializer::class)
|
||||
@EncodeDefault
|
||||
override val type: StickerType.CustomEmoji
|
||||
get() = StickerType.CustomEmoji
|
||||
}
|
||||
@Serializable
|
||||
data class CustomEmojiAnimatedSticker(
|
||||
@@ -426,7 +499,13 @@ data class CustomEmojiAnimatedSticker(
|
||||
override val fileSize: Long? = null,
|
||||
@SerialName(needsRepaintingField)
|
||||
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
|
||||
data class CustomEmojiVideoSticker(
|
||||
@SerialName(fileIdField)
|
||||
@@ -449,7 +528,13 @@ data class CustomEmojiVideoSticker(
|
||||
override val fileSize: Long? = null,
|
||||
@SerialName(needsRepaintingField)
|
||||
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
|
||||
data class UnknownSticker(
|
||||
@@ -471,6 +556,9 @@ data class UnknownSticker(
|
||||
override val fileSize: Long? = null,
|
||||
@SerialName(stickerFormatField)
|
||||
override val stickerFormat: StickerFormat = StickerFormat.Static,
|
||||
@SerialName(stickerTypeField)
|
||||
@Serializable(StickerType.Serializer::class)
|
||||
override val type: StickerType = StickerType.Regular,
|
||||
val raw: JsonElement
|
||||
) : Sticker {
|
||||
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package dev.inmo.tgbotapi.types.message.ChatEvents.forum
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
|
||||
import dev.inmo.tgbotapi.types.webAppNameField
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.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
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.SpoilerableData
|
||||
import dev.inmo.tgbotapi.abstracts.TextedInput
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
@@ -51,6 +52,18 @@ sealed interface MessageContent: ResendableContent {
|
||||
|
||||
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) {
|
||||
subclass(PhotoContent::class)
|
||||
|
||||
@@ -115,6 +128,11 @@ sealed interface MediaCollectionContent<T: TelegramMediaFile>: MessageContent, M
|
||||
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 {
|
||||
val media: TelegramMediaFile
|
||||
fun asTelegramMedia(): TelegramMedia
|
||||
|
||||
@@ -22,7 +22,7 @@ sealed interface DocumentMediaGroupPartContent : MediaGroupPartContent {
|
||||
override fun toMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia
|
||||
}
|
||||
|
||||
sealed interface TextedMediaContent : MediaContent, TextedInput
|
||||
sealed interface TextedMediaContent : TextedContent, MediaContent
|
||||
|
||||
sealed interface MediaGroupCollectionContent<T : MediaGroupPartContent> : TextedMediaContent {
|
||||
@Serializable
|
||||
|
||||
@@ -15,7 +15,7 @@ import kotlinx.serialization.Serializable
|
||||
data class TextContent(
|
||||
override val text: String,
|
||||
override val textSources: TextSourcesList = emptyList(),
|
||||
) : MessageContent, TextedInput {
|
||||
) : TextedContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
messageThreadId: MessageThreadId?,
|
||||
|
||||
@@ -2,6 +2,8 @@ package dev.inmo.tgbotapi.types.message.content
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
|
||||
typealias TextedMessage = CommonMessage<TextedContent>
|
||||
|
||||
typealias InvoiceMessage = CommonMessage<InvoiceContent>
|
||||
typealias VenueMessage = CommonMessage<VenueContent>
|
||||
typealias GameMessage = CommonMessage<GameContent>
|
||||
|
||||
@@ -16,8 +16,8 @@ data class CustomEmojiTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
|
||||
override val subsources: TextSourcesList
|
||||
) : MultilevelTextSource {
|
||||
override val markdown: String by lazy { source.customEmojiMarkdown() }
|
||||
override val markdownV2: String by lazy { source.customEmojiMarkdownV2() }
|
||||
override val html: String by lazy { source.customEmojiHTML() }
|
||||
override val markdownV2: String by lazy { source.customEmojiMarkdownV2(customEmojiId) }
|
||||
override val html: String by lazy { source.customEmojiHTML(customEmojiId) }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE")
|
||||
|
||||
@@ -24,6 +24,7 @@ const val htmlCodeControl = "code"
|
||||
const val htmlPreControl = "pre"
|
||||
const val htmlUnderlineControl = "u"
|
||||
const val htmlStrikethroughControl = "s"
|
||||
const val htmlCustomEmojiControl = "tg-emoji"
|
||||
|
||||
private fun String.markdownDefault(
|
||||
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.customEmojiMarkdown(): String = toMarkdown()
|
||||
internal fun String.customEmojiMarkdownV2(): String = escapeMarkdownV2Common()
|
||||
internal fun String.customEmojiHTML(): String = toHtml()
|
||||
internal fun String.customEmojiMarkdownV2(customEmojiId: CustomEmojiId): String = "!${linkMarkdownV2(customEmojiId.appLink)}"
|
||||
internal fun String.customEmojiHTML(customEmojiId: CustomEmojiId): String = "<$htmlCustomEmojiControl $htmlCustomEmojiControl=\"${customEmojiId.string}\">$this</$htmlCustomEmojiControl>"
|
||||
|
||||
internal fun String.regularMarkdown(): String = toMarkdown()
|
||||
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.FromUser
|
||||
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.SendInvoice
|
||||
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.LoginURLInlineKeyboardButton
|
||||
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.SwitchInlineQueryInlineKeyboardButton
|
||||
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.StickerContent
|
||||
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.VenueContent
|
||||
import dev.inmo.tgbotapi.types.message.content.VideoContent
|
||||
@@ -1013,6 +1016,36 @@ public inline fun <T>
|
||||
WithUser.ifMessageGameShortNameCallbackQuery(block: (MessageGameShortNameCallbackQuery) -> T):
|
||||
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?
|
||||
dev.inmo.tgbotapi.requests.stickers.InputSticker.Mask
|
||||
|
||||
@@ -1898,6 +1931,18 @@ public inline fun <T>
|
||||
InlineKeyboardButton.ifSwitchInlineQueryCurrentChatInlineKeyboardButton(block: (SwitchInlineQueryCurrentChatInlineKeyboardButton) -> T):
|
||||
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():
|
||||
SwitchInlineQueryInlineKeyboardButton? = this as?
|
||||
dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryInlineKeyboardButton
|
||||
@@ -3668,6 +3713,15 @@ public inline fun <T>
|
||||
ResendableContent.ifMediaCollectionContent(block: (MediaCollectionContent<TelegramMediaFile>) -> T):
|
||||
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?
|
||||
dev.inmo.tgbotapi.types.message.content.MediaContent
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ fun makeLinkToMessage(
|
||||
username: Username,
|
||||
messageId: MessageId,
|
||||
threadId: MessageThreadId? = null
|
||||
): String = makeLinkToMessage(username.username, messageId, threadId)
|
||||
): String = makeLinkToMessage(username.usernameWithoutAt, messageId, threadId)
|
||||
fun makeLinkToMessage(
|
||||
chatId: Identifier,
|
||||
messageId: MessageId,
|
||||
|
||||
@@ -103,6 +103,45 @@ inline fun InlineKeyboardRowBuilder.inlineQueryInCurrentChatButton(
|
||||
data: String
|
||||
) = 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]
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user