1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-16 12:00:18 +00:00

Compare commits

...

84 Commits

Author SHA1 Message Date
187f340e88 fixes in webappuser 2023-07-01 14:32:58 +06:00
77ea1f741e fill changelog 2023-07-01 14:30:37 +06:00
bff2713bbd one more fix of triggers 2023-07-01 14:26:46 +06:00
cf666aad11 update gradle wrapper 2023-07-01 14:24:35 +06:00
93e72230a1 update changelog 2023-07-01 14:17:42 +06:00
b81308da8b get back default filters for the queries but fix them 2023-07-01 13:53:26 +06:00
0441b53da2 all query triggers got null default subcontext filter 2023-07-01 03:46:29 +06:00
4853a5b3ad improve docs of onInlineQuery 2023-06-30 22:46:58 +06:00
40a0d2c37d fixes in default filters of updates 2023-06-30 22:42:48 +06:00
2e815a4c37 #773 fix, improvements in updates handling 2023-06-30 16:35:14 +06:00
81ed820602 Migrate onto 9.0.0 and update dependenices
Update libs.versions.toml

Update CHANGELOG.md

Update gradle.properties

Update CHANGELOG.md
2023-06-30 15:22:21 +06:00
b3a657b7d6 make bots username nullable 2023-06-30 14:11:28 +06:00
8247e7c69c add backward compatibility change 2023-06-30 14:11:28 +06:00
67b7472868 Update libs.versions.toml 2023-06-30 02:55:27 +06:00
13e4740d0a improve Update.sourceChat 2023-06-29 13:45:08 +06:00
48db305541 start 8.1.1 2023-06-29 12:18:44 +06:00
6f512a144c Merge pull request #766 from InsanusMokrassar/8.1.0
8.1.0
2023-06-19 22:48:50 +06:00
cf46139bef remove redundant ClassCastsExcluded 2023-06-19 22:14:20 +06:00
14a583e154 update microutils 2023-06-19 21:46:27 +06:00
5b6753c484 small fill of changelog 2023-06-16 14:43:59 +06:00
f153b31464 improve class casts including filtering 2023-06-16 13:50:34 +06:00
6f60ecbf2e fill changelog 2023-06-16 12:14:12 +06:00
9c57ba4da7 rename new Tg methods 2023-06-16 12:12:50 +06:00
d84d982eb4 Merge pull request #768 from klimatov/makeTgDeepLink
added support for the tg:// format for deep links
2023-06-16 12:09:01 +06:00
Pavel Klimatov
2f6f40362a added support for the tg:// format for deep links 2023-06-16 01:54:06 +07:00
e15b18fbcf upgrade up to 8.1.0 2023-06-12 12:34:36 +06:00
ad5cc6ade6 add excluding of impls 2023-06-12 12:25:43 +06:00
6b94215a7c 8.0.2 2023-06-12 10:42:54 +06:00
9c98411bcb Update README.md 2023-06-10 18:16:01 +06:00
b235ab1c28 update dokka version 2023-06-09 12:05:29 +06:00
d4e11494e8 update kdocs of buttons creation shortcuts 2023-06-04 12:38:40 +06:00
e6dbf2bde9 Merge pull request #760 from InsanusMokrassar/8.0.1
8.0.1
2023-06-03 00:58:09 +06:00
5aa0284f28 Update CHANGELOG.md 2023-06-03 00:45:33 +06:00
8b2a50a21f Update libs.versions.toml 2023-06-03 00:44:46 +06:00
a7839df748 Update CHANGELOG.md 2023-06-02 18:00:43 +06:00
3155969954 Update libs.versions.toml 2023-06-02 17:58:53 +06:00
067a0bf229 Update gradle.properties 2023-06-02 17:57:29 +06:00
009991fa88 Merge pull request #754 from InsanusMokrassar/8.0.0
8.0.0
2023-05-31 01:34:34 +06:00
ffbe8fc5e0 Update libs.versions.toml 2023-05-31 01:20:07 +06:00
610ed95296 Update CHANGELOG.md 2023-05-30 14:15:10 +06:00
d3f4a895ff Update libs.versions.toml 2023-05-30 14:14:39 +06:00
51c7c376d7 all previous deprecations have been removed 2023-05-28 20:39:46 +06:00
393197eca1 fixes 2023-05-27 18:33:28 +06:00
67096f8e0e update dependencies 2023-05-27 18:19:14 +06:00
c312a05d6b start 8.0.0 2023-05-27 18:10:52 +06:00
b575695f90 Merge pull request #753 from InsanusMokrassar/7.1.3
7.1.3
2023-05-19 22:50:22 +06:00
65bcf83517 update ClassCasts 2023-05-19 22:42:42 +06:00
f07a179448 InputFile kdocs improvements 2023-05-18 13:06:41 +06:00
ed2c447730 fix of #645 2023-05-18 12:59:35 +06:00
cb4c48d025 waitMediaContent/waitMediaContentMessage/onMediaContent 2023-05-18 11:45:27 +06:00
1a21fa85ac fixes 2023-05-18 11:39:47 +06:00
191fa5406d start 7.1.3 2023-05-11 20:45:24 +06:00
6959dacfc4 Merge pull request #752 from InsanusMokrassar/7.1.2
7.1.2
2023-05-06 13:28:42 +06:00
ced11ab336 downgrade microutils and revert coroutines 2023-05-06 13:25:27 +06:00
6686aef4fa update dependencies in preview mode 2023-05-06 12:25:24 +06:00
9ede545e56 add serialization of Stickers 2023-05-06 12:00:08 +06:00
a74066cf62 start 7.1.2 2023-05-06 11:38:05 +06:00
0a7e99bbb3 Merge pull request #750 from InsanusMokrassar/7.1.1
7.1.1
2023-05-02 01:48:06 +06:00
913f584469 update kotlin poet 2023-05-01 02:15:27 +06:00
20278804bf potential fix of exception printing on skipping of timeout exceptions 2023-05-01 01:52:24 +06:00
631f1b9427 start 7.1.1, update dependencies and add fixes in makeLinkToMessage 2023-04-30 21:00:27 +06:00
5e0106beb5 Update README.md 2023-04-29 11:19:06 +06:00
d37e01f93e Merge pull request #748 from InsanusMokrassar/renovate/ksp
Update ksp to v1.8.21-1.0.11
2023-04-28 00:05:28 +06:00
renovate[bot]
d4492ec7ac Update ksp to v1.8.21-1.0.11 2023-04-27 17:42:32 +00:00
60d24259f4 Merge pull request #747 from InsanusMokrassar/7.1.0
7.1.0
2023-04-22 11:08:29 +06:00
8e6b3b7260 remove redundant class casts 2023-04-22 10:51:37 +06:00
e2cbd5ee0b update deprecation in old updates variables 2023-04-22 10:41:26 +06:00
1e87677ea7 Update ChatMemberUpdated.kt 2023-04-22 01:26:16 +06:00
cb3494cb39 Remove redundant chats folder invite link 2023-04-22 01:24:55 +06:00
ce81be9dcb Update UpdateTypes.kt 2023-04-22 01:10:33 +06:00
2cc02c8c85 Update UpdateTypes.kt 2023-04-22 01:05:34 +06:00
f5b2ee79d6 add info about supported tgbotapi version 2023-04-22 00:28:54 +06:00
0ba6ebb20f add editions for inline messages 2023-04-22 00:18:18 +06:00
3d2df4e255 fixes in SwitchInlineQueryChosenChat 2023-04-21 23:53:53 +06:00
33b6ff1c1e improvements in onDeepLink and waitDeepLink 2023-04-21 23:05:58 +06:00
2859f8ca2f hotfix in buttonField 2023-04-21 22:56:07 +06:00
f1aa67ceda add support of InlineQueryResultsButton 2023-04-21 22:26:11 +06:00
1c66d1e2fc add support of WriteAccessAllowed#webAppName 2023-04-21 21:47:14 +06:00
44e6d7adbc add support of SwitchInlineQueryChosenChatInlineKeyboardButton 2023-04-21 21:42:40 +06:00
61a6d4a880 add support of via_chat_folder_invite_link 2023-04-21 21:13:15 +06:00
e37237cb71 add support of get/set MyName 2023-04-21 20:51:22 +06:00
9a5a196e41 add support of custom emojies in mv2 and html 2023-04-21 20:47:13 +06:00
68f6d8553c start 7.1.0 2023-04-21 18:46:20 +06:00
6fe8e73fca Merge pull request #744 from InsanusMokrassar/7.0.2
7.0.2
2023-04-19 22:53:00 +06:00
106 changed files with 1958 additions and 969 deletions

View File

@@ -1,5 +1,92 @@
# TelegramBotAPI changelog
## 9.0.0
**THIS UPDATE CONTAINS BREAKING CHANGES: USERNAMES OF BOTS NOW BECAME NULLABLE**
* `Version`:
* `Coroutines`: `1.6.4` -> `1.7.1`
* `Ktor`: `2.3.1` -> `2.3.2`
* `MicroUtils`: `0.19.4` -> `0.19.7`
* `Core`:
* **All bots now have nullable usernames just like common users ([#772](https://github.com/InsanusMokrassar/ktgbotapi/issues/772))**
* Decrease possible errors in updates handling by additional handling of update deserialization wrapping ([#773](https://github.com/InsanusMokrassar/ktgbotapi/issues/773))
* New interface `GetUpdatesRequest`. You may implement it to show default telegram bot ktor executor that this
request is an updates request and should be handled in a different way
* Now it is possible to get raw updates with `GetUpdatesRaw` request
* `Utils`:
* Improve extension `Update.sourceChat` to add opportunity to select some chats by logic different with the default
## 8.1.0
**PARTIALLY BREAKING CHANGES: Exclude `.*Impl` classcasts from `ClassCastsNew`**
* `Version`:
* `MicroUtils`: `0.19.2` -> `0.19.4`
* `Utils`:
* Add deep links formatting for internal `tg://` prefix (thanks to [@klimatov](https://github.com/klimatov))
* Exclude `.*Impl` classcasts from `ClassCastsNew`
## 8.0.1
* `Version`:
* `UUID`: `0.7.0` -> `0.7.1`
* `Ktor`: `2.3.0` -> `2.3.1`
* `MicroUtils`: `0.19.1` -> `0.19.2`
## 8.0.0
**THIS UPDATE CONTAINS BREAKING CHANGES**
**ALL PROJECT DEPRECATIONS HAVE BEEN REMOVED**
**IN THIS UPDATE KORLIBS HAVE BEEN UPDATED TO VERSION `4.0.2`. SINCE THAT VERSION A LOT OF PACKAGES HAVE BEEN RENAMED.
MIGRATIONS USED IN THIS LIB:**
* `com.soywiz.klock` -> `korlibs.time`
* `com.soywiz.krypto` -> `korlibs.crypto`
* `Versions`:
* `Korlibs`: `3.4.0` -> `4.0.3`
* `MicroUtils`: `0.18.4` -> `0.19.1`
## 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_

View File

@@ -1,11 +1,11 @@
# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.6-blue)](https://core.telegram.org/bots/api-changelog#march-9-2023)
# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.7-blue)](https://core.telegram.org/bots/api-changelog#april-21-2023)
| Docs | [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue&logo=kotlin)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Bookstack&message=Tutorial&color=blue&logo=bookstack)](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
| Docs | [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue&logo=kotlin)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Mk&message=Docs&color=blue&logo=mkdocs)](https://docs.inmo.dev/tgbotapi/index.html) |
|:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Useful repos | [![Create bot](https://img.shields.io/static/v1?label=Github&message=Template&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![Examples](https://img.shields.io/static/v1?label=Github&message=Examples&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) |
| Misc | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue&logo=google-sheets)](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) |
| Platforms | ![JVM](https://img.shields.io/badge/JVM-red?style=plastic&logo=openjdk&logoColor=white) ![Js](https://img.shields.io/badge/JavaScript-323330?style=plastic&logo=javascript&logoColor=F7DF1E) |
| Experimental Platforms | ![Linux x64](https://img.shields.io/badge/LinuxX64-FCC624?style=plastic&logo=linux&logoColor=black) ![MinGW x64](https://img.shields.io/badge/MinGWX64-black?style=plastic&logo=windows&logoColor=green) |
| Experimental Platforms | [![Linux x64](https://img.shields.io/badge/LinuxX64-FCC624?style=plastic&logo=linux&logoColor=black)](https://kotlinlang.org/docs/native-target-support.html#tier-1) [![MinGW x64](https://img.shields.io/badge/MinGWX64-black?style=plastic&logo=windows&logoColor=green)](https://kotlinlang.org/docs/native-target-support.html#tier-1) |
<!--- [![Telegram Channel](./resources/tg_channel_qr.jpg)](https://t.me/ktgbotapi) --->

View File

@@ -6,4 +6,4 @@ kotlin.incremental=true
kotlin.incremental.js=true
library_group=dev.inmo
library_version=7.0.2
library_version=9.0.0

View File

@@ -1,22 +1,22 @@
[versions]
kotlin = "1.8.20"
kotlin-serialization = "1.5.0"
kotlin-coroutines = "1.6.4"
kotlin = "1.8.22"
kotlin-serialization = "1.5.1"
kotlin-coroutines = "1.7.2"
javax-activation = "1.1.1"
korlibs = "3.4.0"
uuid = "0.7.0"
ktor = "2.3.0"
korlibs = "4.0.3"
uuid = "0.7.1"
ktor = "2.3.2"
ksp = "1.8.20-1.0.11"
kotlin-poet = "1.13.0"
ksp = "1.8.22-1.0.11"
kotlin-poet = "1.14.2"
microutils = "0.17.8"
microutils = "0.19.7"
github-release-plugin = "2.4.1"
dokka = "1.8.10"
dokka = "1.8.20"
[libraries]

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip

View File

@@ -0,0 +1,27 @@
package dev.inmo.tgbotapi.extensions.api
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.GetUpdates
import dev.inmo.tgbotapi.requests.GetUpdatesRaw
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.update.abstracts.Update
suspend fun TelegramBot.getRawUpdates(
offset: UpdateIdentifier? = null,
limit: Int = getUpdatesLimit.last,
timeout: Seconds? = null,
allowed_updates: List<String>? = ALL_UPDATES_LIST
) = execute(
GetUpdatesRaw(
offset, limit, timeout, allowed_updates
)
)
suspend fun TelegramBot.getRawUpdates(
lastUpdate: Update,
limit: Int = getUpdatesLimit.last,
timeout: Seconds? = null,
allowed_updates: List<String>? = ALL_UPDATES_LIST
) = getRawUpdates(
lastUpdate.updateId + 1, limit, timeout, allowed_updates
)

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.extensions.api
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import korlibs.time.DateTime
import korlibs.time.TimeSpan
import dev.inmo.micro_utils.coroutines.LinkedSupervisorJob
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup

View File

@@ -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)

View File

@@ -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))

View File

@@ -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))

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.CreateChatInviteLink
import dev.inmo.tgbotapi.types.ChatIdentifier

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.EditChatInviteLink
import dev.inmo.tgbotapi.types.ChatIdentifier

View File

@@ -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)

View File

@@ -10,7 +10,7 @@ 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.editMessageCaption(
suspend fun TelegramBot.editMessageMedia(
inlineMessageId: InlineMessageIdentifier,
media: TelegramMedia,
replyMarkup: InlineKeyboardMarkup? = null

View File

@@ -72,76 +72,3 @@ suspend fun TelegramBot.setStickerSetThumbnail(
) = setStickerSetThumbnail(
user.id, stickerSet.name, thumbnail
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSetName: String,
thumb: FileId
) = execute(
SetStickerSetThumbnail(userId, thumbSetName, thumb)
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSetName: String,
thumb: MultipartFile
) = execute(
SetStickerSetThumbnail(userId, thumbSetName, thumb)
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSetName: String,
thumb: FileId
) = setStickerSetThumb(
user.id, thumbSetName, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSetName: String,
thumb: MultipartFile
) = setStickerSetThumb(
user.id, thumbSetName, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSet: StickerSet,
thumb: FileId
) = setStickerSetThumb(
userId, thumbSet.name, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSet: StickerSet,
thumb: MultipartFile
) = setStickerSetThumb(
userId, thumbSet.name, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSet: StickerSet,
thumb: FileId
) = setStickerSetThumb(
user.id, thumbSet.name, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSet: StickerSet,
thumb: MultipartFile
) = setStickerSetThumb(
user.id, thumbSet.name, thumb
)

View File

@@ -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>()

View File

@@ -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>()

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.filters
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceUser
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated
@@ -15,7 +16,9 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
* Allow only events from the same chat as base [Message]
*/
val MessageFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, Message, Update> = { message, update ->
update.sourceChat() ?.id == message.chat.id
update.sourceChat() ?.let {
it.id == message.chat.id
} != false
}
/**
* Allow only events from the same chat as base [List] of [Message]
@@ -29,31 +32,41 @@ val MessagesFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, List<Mess
* Allow only updates from the same user as base [CallbackQuery.user]
*/
val CallbackQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, CallbackQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.user.id
update.sourceUser() ?.let {
it.id == query.user.id
} != false
}
/**
* Allow only updates from the same user as base [ShippingQuery.user]
*/
val ShippingQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, ShippingQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.user.id
update.sourceUser() ?.let {
it.id == query.user.id
} != false
}
/**
* Allow only updates from the same user as base [ShippingQuery.user]
*/
val PreCheckoutQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, PreCheckoutQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.user.id
update.sourceUser() ?.let {
it.id == query.user.id
} != false
}
/**
* Allow only updates from the same user as base [InlineQuery.from]
*/
val InlineQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, InlineQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.from.id
update.sourceUser() ?.let {
it.id == query.user.id
} != false
}
/**
* Allow only events from the same chat as base [ChatMemberUpdated]
*/
val ChatMemberUpdatedFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, ChatMemberUpdated, Update> = { updated, update ->
update.sourceChat() ?.id == updated.chat.id
update.sourceChat() ?.let {
it.id == updated.chat.id
} != false
}
/**
* Allow only events from the same chat as base [ChatMemberUpdated]

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.ChatJoinRequestFilterByChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatChatJoinRequestMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
@@ -25,7 +24,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
*/
suspend fun <BC : BehaviourContext> BC.onChatJoinRequest(
initialFilter: SimpleFilter<ChatJoinRequest>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatJoinRequest, Update>? = ChatJoinRequestFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatJoinRequest, Update>? = null,
markerFactory: MarkerFactory<in ChatJoinRequest, Any> = ByChatChatJoinRequestMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatJoinRequest>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {

View File

@@ -22,7 +22,7 @@ internal suspend fun <BC : BehaviourContext> BC.commandUncounted(
commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onText(
@@ -49,7 +49,7 @@ suspend fun <BC : BehaviourContext> BC.command(
commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = runCatchingSafely {
@@ -78,7 +78,7 @@ suspend fun <BC : BehaviourContext> BC.command(
command: String,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = command(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -87,7 +87,7 @@ suspend fun <BC : BehaviourContext> BC.command(
botCommand: BotCommand,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = command(botCommand.command, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -96,7 +96,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = command(commandRegex, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -105,7 +105,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
command: String,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -114,7 +114,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
botCommand: BotCommand,
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onCommand(botCommand.command, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -122,7 +122,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
suspend fun <BC : BehaviourContext> BC.commandWithArgs(
commandRegex: Regex,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = command(
@@ -142,7 +142,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
suspend fun <BC : BehaviourContext> BC.commandWithArgs(
command: String,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = commandWithArgs(
@@ -156,7 +156,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
suspend fun <BC : BehaviourContext> BC.commandWithArgs(
botCommand: BotCommand,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = commandWithArgs(
@@ -170,7 +170,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
commandRegex: Regex,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = commandWithArgs(commandRegex, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -178,7 +178,7 @@ suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
command: String,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = onCommandWithArgs(command.toRegex(), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -186,7 +186,7 @@ suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
botCommand: BotCommand,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = onCommandWithArgs(botCommand.command, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -20,7 +20,7 @@ import kotlinx.coroutines.Job
suspend fun <BC : BehaviourContext> BC.unhandledCommand(
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onText(
@@ -48,7 +48,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommand(
suspend fun <BC : BehaviourContext> BC.onUnhandledCommand(
requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = unhandledCommand(requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -56,7 +56,7 @@ suspend fun <BC : BehaviourContext> BC.onUnhandledCommand(
@PreviewFeature
suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>>
) = onUnhandledCommand(
@@ -74,7 +74,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs(
@PreviewFeature
suspend fun <BC : BehaviourContext> BC.onUnhandledCommandWithArgs(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>>
): Job = unhandledCommandWithArgs(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -46,7 +46,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent>
*/
suspend fun <BC : BehaviourContext> BC.onContentMessage(
initialFilter: CommonMessageFilter<MessageContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MessageContent>, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MessageContent>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<MessageContent>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MessageContent>>
) = onContentMessageWithType(
@@ -70,7 +70,7 @@ suspend fun <BC : BehaviourContext> BC.onContentMessage(
*/
suspend fun <BC : BehaviourContext> BC.onContact(
initialFilter: CommonMessageFilter<ContactContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage>
) = onContentMessageWithType(
@@ -94,7 +94,7 @@ suspend fun <BC : BehaviourContext> BC.onContact(
*/
suspend fun <BC : BehaviourContext> BC.onDice(
initialFilter: CommonMessageFilter<DiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage>
) = onContentMessageWithType(
@@ -118,7 +118,7 @@ suspend fun <BC : BehaviourContext> BC.onDice(
*/
suspend fun <BC : BehaviourContext> BC.onGame(
initialFilter: CommonMessageFilter<GameContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage>
) = onContentMessageWithType(
@@ -142,7 +142,7 @@ suspend fun <BC : BehaviourContext> BC.onGame(
*/
suspend fun <BC : BehaviourContext> BC.onLocation(
initialFilter: CommonMessageFilter<LocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage>
) = onContentMessageWithType(
@@ -166,7 +166,7 @@ suspend fun <BC : BehaviourContext> BC.onLocation(
*/
suspend fun <BC : BehaviourContext> BC.onLiveLocation(
initialFilter: CommonMessageFilter<LiveLocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LiveLocationMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LiveLocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in LiveLocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LiveLocationMessage>
) = onContentMessageWithType(
@@ -190,7 +190,7 @@ suspend fun <BC : BehaviourContext> BC.onLiveLocation(
*/
suspend fun <BC : BehaviourContext> BC.onStaticLocation(
initialFilter: CommonMessageFilter<StaticLocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StaticLocationMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StaticLocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StaticLocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StaticLocationMessage>
) = onContentMessageWithType(
@@ -214,7 +214,7 @@ suspend fun <BC : BehaviourContext> BC.onStaticLocation(
*/
suspend fun <BC : BehaviourContext> BC.onPoll(
initialFilter: CommonMessageFilter<PollContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in PollMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollMessage>
) = onContentMessageWithType(
@@ -238,7 +238,7 @@ suspend fun <BC : BehaviourContext> BC.onPoll(
*/
suspend fun <BC : BehaviourContext> BC.onText(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = onContentMessageWithType(
@@ -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,
@@ -262,7 +286,7 @@ suspend fun <BC : BehaviourContext> BC.onText(
*/
suspend fun <BC : BehaviourContext> BC.onVenue(
initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage>
) = onContentMessageWithType(
@@ -286,7 +310,7 @@ suspend fun <BC : BehaviourContext> BC.onVenue(
*/
suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
initialFilter: CommonMessageFilter<AudioMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage>
) = onContentMessageWithType(
@@ -310,7 +334,7 @@ suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
*/
suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
initialFilter: CommonMessageFilter<DocumentMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage>
) = onContentMessageWithType(
@@ -334,7 +358,7 @@ suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
*/
suspend fun <BC : BehaviourContext> BC.onTextedMediaContent(
initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage>
) = onContentMessageWithType(
@@ -358,7 +382,7 @@ suspend fun <BC : BehaviourContext> BC.onTextedMediaContent(
*/
suspend fun <BC : BehaviourContext> BC.onMediaCollection(
initialFilter: CommonMessageFilter<MediaCollectionContent<TelegramMediaFile>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>>
) = onContentMessageWithType(
@@ -382,7 +406,7 @@ suspend fun <BC : BehaviourContext> BC.onMediaCollection(
*/
suspend fun <BC : BehaviourContext> BC.onMedia(
initialFilter: CommonMessageFilter<MediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
) = onContentMessageWithType(
@@ -406,7 +430,7 @@ suspend fun <BC : BehaviourContext> BC.onMedia(
*/
suspend fun <BC : BehaviourContext> BC.onAnimation(
initialFilter: CommonMessageFilter<AnimationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage>
) = onContentMessageWithType(
@@ -430,7 +454,7 @@ suspend fun <BC : BehaviourContext> BC.onAnimation(
*/
suspend fun <BC : BehaviourContext> BC.onAudio(
initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage>
) = onContentMessageWithType(
@@ -454,7 +478,7 @@ suspend fun <BC : BehaviourContext> BC.onAudio(
*/
suspend fun <BC : BehaviourContext> BC.onDocument(
initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage>
) = onContentMessageWithType(
@@ -478,7 +502,7 @@ suspend fun <BC : BehaviourContext> BC.onDocument(
*/
suspend fun <BC : BehaviourContext> BC.onPhoto(
initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage>
) = onContentMessageWithType(
@@ -502,7 +526,7 @@ suspend fun <BC : BehaviourContext> BC.onPhoto(
*/
suspend fun <BC : BehaviourContext> BC.onSticker(
initialFilter: CommonMessageFilter<StickerContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage>
) = onContentMessageWithType(
@@ -526,7 +550,7 @@ suspend fun <BC : BehaviourContext> BC.onSticker(
*/
suspend fun <BC : BehaviourContext> BC.onVideo(
initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage>
) = onContentMessageWithType(
@@ -550,7 +574,7 @@ suspend fun <BC : BehaviourContext> BC.onVideo(
*/
suspend fun <BC : BehaviourContext> BC.onVideoNote(
initialFilter: CommonMessageFilter<VideoNoteContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage>
) = onContentMessageWithType(
@@ -574,7 +598,7 @@ suspend fun <BC : BehaviourContext> BC.onVideoNote(
*/
suspend fun <BC : BehaviourContext> BC.onVoice(
initialFilter: CommonMessageFilter<VoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage>
) = onContentMessageWithType(
@@ -598,7 +622,7 @@ suspend fun <BC : BehaviourContext> BC.onVoice(
*/
suspend fun <BC : BehaviourContext> BC.onInvoice(
initialFilter: CommonMessageFilter<InvoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage>
) = onContentMessageWithType(
@@ -622,7 +646,7 @@ suspend fun <BC : BehaviourContext> BC.onInvoice(
*/
suspend fun <BC : BehaviourContext> BC.onVisualContent(
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VisualMediaGroupMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VisualMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VisualMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VisualMediaGroupMessage>
) = onContentMessageWithType(
@@ -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
)

View File

@@ -24,7 +24,7 @@ import kotlinx.coroutines.flow.filter
private val startRegex = Regex("start")
suspend fun <BC : BehaviourContext> BC.onDeepLink(
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) },
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 = on(
@@ -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)

View File

@@ -40,7 +40,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent>
*/
suspend fun <BC : BehaviourContext> BC.onEditedContentMessage(
initialFilter: CommonMessageFilter<MessageContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MessageContent>, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MessageContent>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<MessageContent>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MessageContent>>
)= onEditedContent(
@@ -64,7 +64,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedContentMessage(
*/
suspend fun <BC : BehaviourContext> BC.onEditedContact(
initialFilter: CommonMessageFilter<ContactContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage>
)= onEditedContent(
@@ -88,7 +88,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedContact(
*/
suspend fun <BC : BehaviourContext> BC.onEditedDice(
initialFilter: CommonMessageFilter<DiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage>
)= onEditedContent(
@@ -112,7 +112,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedDice(
*/
suspend fun <BC : BehaviourContext> BC.onEditedGame(
initialFilter: CommonMessageFilter<GameContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage>
)= onEditedContent(
@@ -136,7 +136,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedGame(
*/
suspend fun <BC : BehaviourContext> BC.onEditedLocation(
initialFilter: CommonMessageFilter<LocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage>
)= onEditedContent(
@@ -160,7 +160,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedLocation(
*/
suspend fun <BC : BehaviourContext> BC.onEditedText(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
)= onEditedContent(
@@ -184,7 +184,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedText(
*/
suspend fun <BC : BehaviourContext> BC.onEditedVenue(
initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage>
)= onEditedContent(
@@ -208,7 +208,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVenue(
*/
suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup(
initialFilter: CommonMessageFilter<AudioMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage>
)= onEditedContent(
@@ -232,7 +232,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup(
*/
suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
initialFilter: CommonMessageFilter<DocumentMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage>
)= onEditedContent(
@@ -256,7 +256,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
*/
suspend fun <BC : BehaviourContext> BC.onEditedTextedMediaContent(
initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage>
)= onEditedContent(
@@ -280,7 +280,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedTextedMediaContent(
*/
suspend fun <BC : BehaviourContext> BC.onEditedMediaCollection(
initialFilter: CommonMessageFilter<MediaCollectionContent<TelegramMediaFile>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>>
)= onEditedContent(
@@ -304,7 +304,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedMediaCollection(
*/
suspend fun <BC : BehaviourContext> BC.onEditedMedia(
initialFilter: CommonMessageFilter<MediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
)= onEditedContent(
@@ -328,7 +328,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedMedia(
*/
suspend fun <BC : BehaviourContext> BC.onEditedAnimation(
initialFilter: CommonMessageFilter<AnimationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage>
)= onEditedContent(
@@ -352,7 +352,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedAnimation(
*/
suspend fun <BC : BehaviourContext> BC.onEditedAudio(
initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage>
)= onEditedContent(
@@ -376,7 +376,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedAudio(
*/
suspend fun <BC : BehaviourContext> BC.onEditedDocument(
initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage>
)= onEditedContent(
@@ -400,7 +400,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedDocument(
*/
suspend fun <BC : BehaviourContext> BC.onEditedPhoto(
initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage>
)= onEditedContent(
@@ -424,7 +424,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedPhoto(
*/
suspend fun <BC : BehaviourContext> BC.onEditedSticker(
initialFilter: CommonMessageFilter<StickerContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage>
)= onEditedContent(
@@ -448,7 +448,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedSticker(
*/
suspend fun <BC : BehaviourContext> BC.onEditedVideo(
initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage>
)= onEditedContent(
@@ -472,7 +472,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVideo(
*/
suspend fun <BC : BehaviourContext> BC.onEditedVideoNote(
initialFilter: CommonMessageFilter<VideoNoteContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage>
)= onEditedContent(
@@ -496,7 +496,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVideoNote(
*/
suspend fun <BC : BehaviourContext> BC.onEditedVoice(
initialFilter: CommonMessageFilter<VoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage>
)= onEditedContent(
@@ -520,7 +520,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVoice(
*/
suspend fun <BC : BehaviourContext> BC.onEditedInvoice(
initialFilter: CommonMessageFilter<InvoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update> = MessageFilterByChat,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage>
)= onEditedContent(

View File

@@ -20,7 +20,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : InlineQuery> BC.
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* @param subcontextUpdatesFilter **Default is [InlineQueryFilterByUser]]**. 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]
@@ -40,7 +40,7 @@ suspend fun <BC : BehaviourContext> BC.onAnyInlineQuery(
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* @param subcontextUpdatesFilter **Default is [InlineQueryFilterByUser]]**. 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]
@@ -60,7 +60,7 @@ suspend fun <BC : BehaviourContext> BC.onBaseInlineQuery(
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* @param subcontextUpdatesFilter **Default is [InlineQueryFilterByUser]]**. 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]

View File

@@ -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)

View File

@@ -8,7 +8,7 @@ import dev.inmo.tgbotapi.types.chat.User
*
* @see FromUser
*/
@ClassCastsIncluded
@ClassCastsIncluded(excludeRegex = ".*Impl")
interface WithUser {
val user: User
}

View File

@@ -5,5 +5,3 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
interface WithReplyMarkup {
val replyMarkup: KeyboardMarkup?
}
@Deprecated("Renamed", ReplaceWith("WithReplyMarkup", "dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup"))
typealias ReplyMarkup = WithReplyMarkup

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.bot.exceptions
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.types.RetryAfterError
import io.ktor.utils.io.errors.IOException

View File

@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.requests.GetUpdates
import dev.inmo.tgbotapi.requests.GetUpdatesRequest
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
@@ -35,7 +35,7 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
)
accept(ContentType.Application.Json)
if (request is GetUpdates) {
if (request is GetUpdatesRequest) {
request.timeout?.times(1000L) ?.let { customTimeoutMillis ->
if (customTimeoutMillis > 0) {
timeout {

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.bot.settings.limiters
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MilliSeconds
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Semaphore
@@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlin.math.roundToLong
private fun now(): Long = DateTime.nowUnixLong()
private fun now(): Long = DateTime.nowUnixMillisLong()
@Serializable
class CommonLimiter(

View File

@@ -14,7 +14,6 @@ object ExceptionsOnlyLimiter : RequestLimiter {
result = runCatchingSafely {
block()
}.onFailure {
it.printStackTrace()
if (it is TooMuchRequestsException) {
delay(it.retryAfter.leftToRetry)
} else {

View File

@@ -22,13 +22,11 @@ private val updatesListSerializer = ListSerializer(
*/
@Serializable
data class GetUpdates(
val offset: UpdateIdentifier? = null,// set `last update id + 1` to receive next part of updates
val limit: Int = getUpdatesLimit.last,
val timeout: Seconds? = null,
val allowed_updates: List<String>? = ALL_UPDATES_LIST
): SimpleRequest<List<Update>> {
override fun method(): String = "getUpdates"
override val offset: UpdateIdentifier? = null,// set `last update id + 1` to receive next part of updates
override val limit: Int = getUpdatesLimit.last,
override val timeout: Seconds? = null,
override val allowed_updates: List<String>? = ALL_UPDATES_LIST
): GetUpdatesRequest<List<Update>> {
override val resultDeserializer: DeserializationStrategy<List<Update>>
get() = updatesListSerializer

View File

@@ -0,0 +1,37 @@
package dev.inmo.tgbotapi.requests
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ALL_UPDATES_LIST
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.getUpdatesLimit
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.json.JsonArray
/**
* Raw variant of [GetUpdates]. This type will be useful in case you wish to get some updates and handle them by
* yourself or with [dev.inmo.tgbotapi.utils.convertWithMediaGroupUpdates]
*/
@Serializable
data class GetUpdatesRaw(
override val offset: UpdateIdentifier? = null,// set `last update id + 1` to receive next part of updates
override val limit: Int = getUpdatesLimit.last,
override val timeout: Seconds? = null,
override val allowed_updates: List<String>? = ALL_UPDATES_LIST
): GetUpdatesRequest<JsonArray> {
override fun method(): String = "getUpdates"
override val resultDeserializer: DeserializationStrategy<JsonArray>
get() = JsonArray.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
init {
if (limit !in getUpdatesLimit) {
error("GetUpdates request can be called only with limit in range $getUpdatesLimit (actual value is $limit)")
}
}
}

View File

@@ -0,0 +1,17 @@
package dev.inmo.tgbotapi.requests
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ALL_UPDATES_LIST
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.getUpdatesLimit
interface GetUpdatesRequest<T : Any> : SimpleRequest<T> {
val offset: UpdateIdentifier?
val limit: Int
val timeout: Seconds?
val allowed_updates: List<String>?
override fun method(): String = "getUpdates"
}

View File

@@ -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)
}
}

View File

@@ -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,

View File

@@ -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,
)
)
}
}

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.abstracts
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.DeserializationStrategy

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.*

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.*

View File

@@ -2,8 +2,4 @@ package dev.inmo.tgbotapi.requests.send.abstracts
interface ThumbedSendMessageRequest<T: Any>: SendMessageRequest<T> {
val thumbnail: String?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnail"))
val thumb: String?
get() = thumbnail
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.send.polls
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.TextedOutput
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest

View File

@@ -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
)

View File

@@ -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
@@ -76,9 +77,6 @@ val UserId.userLink: String
get() = chatId.userLink
val User.userLink: String
get() = id.userLink
@Deprecated("Deprecated due to the conflicts in name", ReplaceWith("this.userLink", "dev.inmo.tgbotapi.types.userLink"))
val User.link: String
get() = userLink
typealias UserId = ChatId

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.WithUser
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.utils.RiskFeature

View File

@@ -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"
@@ -365,17 +375,9 @@ const val stickerFileIdField = "sticker_file_id"
const val gameShortNameField = "game_short_name"
const val thumbnailUrlField = "thumbnail_url"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailUrlField", "dev.inmo.tgbotapi.types.thumbnailUrlField"))
const val thumbUrlField = "thumb_url"
const val thumbnailMimeTypeField = "thumbnail_mime_type"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailMimeTypeField", "dev.inmo.tgbotapi.types.thumbnailMimeTypeField"))
const val thumbMimeTypeField = "thumb_mime_type"
const val thumbnailWidthField = "thumbnail_width"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailWidthField", "dev.inmo.tgbotapi.types.thumbnailWidthField"))
const val thumbWidthField = "thumb_width"
const val thumbnailHeightField = "thumbnail_height"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailHeightField", "dev.inmo.tgbotapi.types.thumbnailHeightField"))
const val thumbHeightField = "thumb_height"
const val inputMessageContentField = "input_message_content"
const val hideUrlField = "hide_url"
@@ -430,8 +432,6 @@ const val idField = "id"
const val pollIdField = "poll_id"
const val textField = "text"
const val thumbnailField = "thumbnail"
@Deprecated("Renamed (in telegram bot api)", ReplaceWith("thumbnailField", "dev.inmo.tgbotapi.types.thumbnailField"))
const val thumbField = "thumb"
const val emojiField = "emoji"
const val emojisField = "emojis"
const val titleField = "title"
@@ -596,4 +596,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"

View File

@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.Serializable
@Serializable(InlineQueryResultSerializer::class)
@ClassCastsIncluded
@ClassCastsIncluded(excludeRegex = ".*Impl")
interface InlineQueryResult {
val type: String
val id: InlineQueryIdentifier

View File

@@ -2,11 +2,5 @@ package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts
interface ThumbSizedInlineQueryResult : InlineQueryResult, ThumbedInlineQueryResult {
val thumbnailWidth: Int?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailWidth"))
val thumbWidth: Int?
get() = thumbnailWidth
val thumbnailHeight: Int?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailHeight"))
val thumbHeight: Int?
get() = thumbnailHeight
}

View File

@@ -4,14 +4,8 @@ import dev.inmo.tgbotapi.utils.MimeType
interface ThumbedInlineQueryResult : InlineQueryResult {
val thumbnailUrl: String?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailUrl"))
val thumbUrl: String?
get() = thumbnailUrl
}
interface ThumbedWithMimeTypeInlineQueryResult : ThumbedInlineQueryResult {
val thumbnailMimeType: MimeType?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailMimeType"))
val thumbMimeType: MimeType?
get() = thumbnailMimeType
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
sealed class RequestError
@@ -10,7 +10,7 @@ data class RetryAfterError(
) : RequestError() {
val canContinue = (seconds * 1000L) + startCountingMillis
val leftToRetry: Long
get() = canContinue - DateTime.nowUnixLong()
get() = canContinue - DateTime.nowUnixMillisLong()
}
data class MigrateChatId(

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import kotlinx.serialization.*
@Serializable

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer

View File

@@ -11,9 +11,9 @@ 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"
val ALL_UPDATES_LIST = listOf(
UPDATE_MESSAGE,
@@ -27,7 +27,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
)

View File

@@ -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

View File

@@ -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)

View File

@@ -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"
}
}
}

View File

@@ -5,20 +5,14 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.*
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
/**
* Creates and put [PayInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [PayInlineKeyboardButton]
*/
inline fun payInlineButton(
text: String
) = PayInlineKeyboardButton(text)
/**
* Creates and put [CallbackDataInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [CallbackDataInlineKeyboardButton]
*/
inline fun dataInlineButton(
text: String,
@@ -26,20 +20,14 @@ inline fun dataInlineButton(
) = CallbackDataInlineKeyboardButton(text, data)
/**
* Creates and put [CallbackGameInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [CallbackGameInlineKeyboardButton]
*/
inline fun gameInlineButton(
text: String
) = CallbackGameInlineKeyboardButton(text)
/**
* Creates and put [LoginURLInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [LoginURLInlineKeyboardButton]
*/
inline fun loginInlineButton(
text: String,
@@ -47,10 +35,7 @@ inline fun loginInlineButton(
) = LoginURLInlineKeyboardButton(text, loginUrl)
/**
* Creates and put [SwitchInlineQueryCurrentChatInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [SwitchInlineQueryCurrentChatInlineKeyboardButton]
*/
inline fun inlineQueryInCurrentChatInlineButton(
text: String,
@@ -58,10 +43,44 @@ inline fun inlineQueryInCurrentChatInlineButton(
) = SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data)
/**
* Creates and put [SwitchInlineQueryInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [SwitchInlineQueryChosenChatInlineKeyboardButton]
*/
inline fun inlineQueryInCurrentChatInlineButton(
text: String,
parameters: SwitchInlineQueryChosenChat
) = SwitchInlineQueryChosenChatInlineKeyboardButton(text, parameters)
/**
* Creates [SwitchInlineQueryChosenChatInlineKeyboardButton]
*/
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 [SwitchInlineQueryChosenChatInlineKeyboardButton]
*/
inline fun inlineQueryInAnyCurrentChatInlineButton(
text: String,
query: String? = null,
) = inlineQueryInCurrentChatInlineButton(text, query, allowUsers = true, allowBots = true, allowGroups = true, allowChannels = true)
/**
* Creates [SwitchInlineQueryInlineKeyboardButton]
*/
inline fun inlineQueryInlineButton(
text: String,
@@ -69,10 +88,7 @@ inline fun inlineQueryInlineButton(
) = SwitchInlineQueryInlineKeyboardButton(text, data)
/**
* Creates and put [URLInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [URLInlineKeyboardButton]
*/
inline fun urlInlineButton(
text: String,
@@ -80,10 +96,7 @@ inline fun urlInlineButton(
) = URLInlineKeyboardButton(text, url)
/**
* Creates and put [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only
*/
inline fun webAppInlineButton(
text: String,
@@ -91,10 +104,7 @@ inline fun webAppInlineButton(
) = WebAppInlineKeyboardButton(text, webApp)
/**
* Creates and put [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
* Creates [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only
*/
inline fun webAppInlineButton(
text: String,

View File

@@ -8,40 +8,28 @@ import dev.inmo.tgbotapi.types.webapps.WebAppInfo
/**
* Creates and put [SimpleKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [SimpleKeyboardButton]
*/
inline fun simpleReplyButton(
text: String
) = SimpleKeyboardButton(text)
/**
* Creates and put [RequestContactKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestContactKeyboardButton]
*/
inline fun requestContactReplyButton(
text: String
) = RequestContactKeyboardButton(text)
/**
* Creates and put [RequestLocationKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestLocationKeyboardButton]
*/
inline fun requestLocationReplyButton(
text: String
) = RequestLocationKeyboardButton(text)
/**
* Creates and put [RequestPollKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestPollKeyboardButton]
*/
inline fun requestPollReplyButton(
text: String,
@@ -49,10 +37,7 @@ inline fun requestPollReplyButton(
) = RequestPollKeyboardButton(text, pollType)
/**
* Creates and put [WebAppKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [WebAppKeyboardButton]
*/
inline fun webAppReplyButton(
text: String,
@@ -60,10 +45,7 @@ inline fun webAppReplyButton(
) = WebAppKeyboardButton(text, webApp)
/**
* Creates and put [WebAppKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [WebAppKeyboardButton]
*/
inline fun webAppReplyButton(
text: String,
@@ -72,10 +54,7 @@ inline fun webAppReplyButton(
/**
* Creates and put [RequestUserKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestUserKeyboardButton]
*/
inline fun requestUserReplyButton(
text: String,
@@ -86,10 +65,7 @@ inline fun requestUserReplyButton(
)
/**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Bot]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Bot]
*/
inline fun requestBotReplyButton(
text: String,
@@ -100,10 +76,7 @@ inline fun requestBotReplyButton(
)
/**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Common]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Common]
*/
inline fun requestUserReplyButton(
text: String,
@@ -115,10 +88,7 @@ inline fun requestUserReplyButton(
)
/**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Any]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Any]
*/
inline fun requestUserOrBotReplyButton(
text: String,
@@ -130,10 +100,7 @@ inline fun requestUserOrBotReplyButton(
/**
* Creates and put [RequestChatKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestChatKeyboardButton]
*/
inline fun requestChatReplyButton(
text: String,
@@ -144,10 +111,7 @@ inline fun requestChatReplyButton(
)
/**
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestChatKeyboardButton] with [KeyboardButtonRequestChat]
*/
inline fun requestChatReplyButton(
text: String,
@@ -174,10 +138,7 @@ inline fun requestChatReplyButton(
)
/**
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Channel]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Channel]
*/
inline fun requestChannelReplyButton(
text: String,
@@ -201,10 +162,7 @@ inline fun requestChannelReplyButton(
/**
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Group]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
* Creates [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Group]
*/
inline fun requestChannelReplyButton(
text: String,

View File

@@ -49,7 +49,7 @@ sealed interface AbleToAddInAttachmentMenuChat : Chat {
}
@Serializable(PreviewChatSerializer::class)
@ClassCastsIncluded
@ClassCastsIncluded(excludeRegex = ".*Impl")
sealed interface Chat {
val id: IdChatIdentifier
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.chat
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.FromUser
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.SerialName

View File

@@ -3,11 +3,13 @@ package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedChannelChat due")
data class ExtendedChannelChatImpl(
@SerialName(idField)
override val id: ChatId,
@@ -33,6 +35,7 @@ data class ExtendedChannelChatImpl(
) : ExtendedChannelChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedGroupChat due")
data class ExtendedGroupChatImpl(
@SerialName(idField)
override val id: ChatId,
@@ -54,6 +57,7 @@ data class ExtendedGroupChatImpl(
) : ExtendedGroupChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedPrivateChat due")
data class ExtendedPrivateChatImpl(
@SerialName(idField)
override val id: UserId,
@@ -80,6 +84,7 @@ data class ExtendedPrivateChatImpl(
typealias ExtendedUser = ExtendedPrivateChatImpl
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedSupergroupChat due")
data class ExtendedSupergroupChatImpl(
@SerialName(idField)
override val id: ChatId,
@@ -121,6 +126,7 @@ data class ExtendedSupergroupChatImpl(
) : ExtendedSupergroupChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedForumChat due")
data class ExtendedForumChatImpl(
@SerialName(idField)
override val id: IdChatIdentifier,
@@ -164,12 +170,12 @@ data class ExtendedForumChatImpl(
@Serializable
data class ExtendedBot(
override val id: UserId,
@SerialName(usernameField)
override val username: Username,
@SerialName(firstNameField)
override val firstName: String,
@SerialName(lastNameField)
override val lastName: String = "",
@SerialName(usernameField)
override val username: Username? = null,
@SerialName(canJoinGroupsField)
val canJoinGroups: Boolean = false,
@SerialName(canReadAllGroupMessagesField)

View File

@@ -4,10 +4,12 @@ import dev.inmo.micro_utils.language_codes.IetfLanguageCode
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use GroupChat due")
data class GroupChatImpl(
@SerialName(idField)
override val id: ChatId,
@@ -16,6 +18,7 @@ data class GroupChatImpl(
) : GroupChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use PrivateChat due")
data class PrivateChatImpl(
@SerialName(idField)
override val id: UserId,
@@ -28,6 +31,7 @@ data class PrivateChatImpl(
) : PrivateChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use SupergroupChat due")
data class SupergroupChatImpl(
@SerialName(idField)
override val id: ChatId,
@@ -38,6 +42,7 @@ data class SupergroupChatImpl(
) : SupergroupChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ForumChat due")
data class ForumChatImpl(
@SerialName(idField)
override val id: IdChatIdentifier,
@@ -48,6 +53,7 @@ data class ForumChatImpl(
) : ForumChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use ChannelChat due")
data class ChannelChatImpl(
@SerialName(idField)
override val id: ChatId,
@@ -61,19 +67,17 @@ data class ChannelChatImpl(
sealed class User : PrivateChat
@Serializable(UserSerializer::class)
sealed class Bot : User() {
abstract override val username: Username
}
sealed class Bot : User()
@Serializable
data class CommonBot(
override val id: UserId,
@SerialName(usernameField)
override val username: Username,
@SerialName(firstNameField)
override val firstName: String,
@SerialName(lastNameField)
override val lastName: String = ""
override val lastName: String = "",
@SerialName(usernameField)
override val username: Username? = null,
) : Bot() {
@SerialName(isBotField)
private val isBot = true

View File

@@ -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

View File

@@ -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(

View File

@@ -2,8 +2,4 @@ package dev.inmo.tgbotapi.types.files
sealed interface ThumbedMediaFile : TelegramMediaFile {
val thumbnail: PhotoSize?
@Deprecated("Renamed (in telegram bot api)", ReplaceWith("thumbnail"))
val thumb: PhotoSize?
get() = thumbnail
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.ChannelChat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent

View File

@@ -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

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import com.soywiz.klock.TimeSpan
import com.soywiz.klock.seconds
import korlibs.time.TimeSpan
import korlibs.time.seconds
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.durationField
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.GroupChat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.SupergroupChat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.*

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.Chat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.*

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message.abstracts
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.WithChat
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.MessageId
@@ -11,7 +11,7 @@ import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@ClassCastsIncluded
@ClassCastsIncluded(excludeRegex = ".*Impl")
interface Message : WithChat {
val messageId: MessageId
val date: DateTime

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.message.abstracts
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
interface PossiblyEditedMessage : Message {
val editDate: DateTime?
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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?,

View File

@@ -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>

View File

@@ -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")

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.polls
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import korlibs.time.DateTime
import korlibs.time.TimeSpan
import dev.inmo.tgbotapi.abstracts.TextedInput
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.*

View File

@@ -32,9 +32,6 @@ sealed interface StickerSet {
val isVideo: Boolean
get() = false
val thumbnail: PhotoSize?
@Deprecated("Renamed in telegram bot api")
val thumb: PhotoSize?
get() = thumbnail
object Serializer : KSerializer<StickerSet> {
override val descriptor: SerialDescriptor = JsonElement.serializer().descriptor

View File

@@ -67,20 +67,19 @@ internal data class RawUpdate constructor(
chat_join_request != null -> ChatJoinRequestUpdate(updateId, chat_join_request)
else -> UnknownUpdate(
updateId,
raw.toString(),
raw
)
}
} catch (e: Error) {
when (e) {
is SerializationException,
is NotImplementedError -> UnknownUpdate(
updateId,
raw.toString(),
raw
)
else -> throw e
}
} catch (e: NotImplementedError) {
UnknownUpdate(
updateId,
raw
)
} catch (e: SerializationException) {
UnknownUpdate(
updateId,
raw
)
}.also {
initedUpdate = it
}

View File

@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.update.abstracts
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.update.RawUpdate
import dev.inmo.tgbotapi.types.updateIdField
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.*
@@ -10,6 +11,9 @@ import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.longOrNull
@ClassCastsIncluded
interface Update {
@@ -19,9 +23,12 @@ interface Update {
data class UnknownUpdate(
override val updateId: UpdateIdentifier,
override val data: String,
override val data: JsonElement,
val throwable: Throwable? = null
) : Update {
val rawJson: JsonElement
) : Update
get() = data
}
@RiskFeature
object UpdateSerializerWithoutSerialization : KSerializer<Update> {
@@ -44,11 +51,19 @@ object UpdateDeserializationStrategy : DeserializationStrategy<Update> {
override fun deserialize(decoder: Decoder): Update {
val asJson = JsonElement.serializer().deserialize(decoder)
return nonstrictJsonFormat.decodeFromJsonElement(
RawUpdate.serializer(),
asJson
).asUpdate(
asJson
)
return runCatching {
nonstrictJsonFormat.decodeFromJsonElement(
RawUpdate.serializer(),
asJson
).asUpdate(
asJson
)
}.getOrElse {
UnknownUpdate(
(asJson as? JsonObject) ?.get(updateIdField) ?.jsonPrimitive ?.longOrNull ?: -1L,
asJson,
it
)
}
}
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.utils
import com.soywiz.krypto.*
import korlibs.crypto.*
import io.ktor.http.decodeURLQueryComponent
import io.ktor.utils.io.core.toByteArray

View File

@@ -1,5 +1,13 @@
package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.utils.RiskFeature
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
internal annotation class ClassCastsIncluded
@RiskFeature("It is internal API in tgbotapi.core and should not be used outside")
annotation class ClassCastsIncluded(val typesRegex: String = "", val excludeRegex: String = "")
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
@RiskFeature("It is internal API in tgbotapi.core and should not be used outside")
annotation class ClassCastsExcluded

View File

@@ -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()

View File

@@ -1,12 +1,12 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.TestsJsonFormat
import kotlinx.serialization.Serializable
import kotlin.test.Test
import kotlin.test.assertEquals
private val dateTimeUnix = DateTime.nowUnixLong()
private val dateTimeUnix = DateTime.nowUnixMillisLong()
private val dateTimeMillis = dateTimeUnix * 1000
private val dateTime = DateTime(dateTimeMillis)

View File

@@ -9,4 +9,5 @@ repositories {
dependencies {
implementation libs.kotlin.poet
implementation libs.ksp
implementation project(":tgbotapi.core")
}

View File

@@ -1,12 +1,21 @@
package dev.inmo.tgbotapi.ksp.processor
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAllSuperTypes
import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.isAnnotationPresent
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.asClassName
import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.ksp.writeTo
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.ClassCastsExcluded
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import java.io.File
class TelegramBotAPISymbolProcessor(
@@ -15,24 +24,51 @@ class TelegramBotAPISymbolProcessor(
private val outputFile: String = "Output",
private val outputFolder: String? = null
) : SymbolProcessor {
private val classCastsIncludedClassName = ClassCastsIncluded::class.asClassName()
@OptIn(KspExperimental::class, RiskFeature::class)
override fun process(resolver: Resolver): List<KSAnnotated> {
val classes = resolver.getSymbolsWithAnnotation("dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded").filterIsInstance<KSClassDeclaration>()
val classes = resolver.getSymbolsWithAnnotation(classCastsIncludedClassName.canonicalName).filterIsInstance<KSClassDeclaration>()
val classesRegexes: Map<KSClassDeclaration, Pair<Regex?, Regex?>> = classes.mapNotNull {
it to (it.getAnnotationsByType(ClassCastsIncluded::class).firstNotNullOfOrNull {
it.typesRegex.takeIf { it.isNotEmpty() } ?.let(::Regex) to it.excludeRegex.takeIf { it.isNotEmpty() } ?.let(::Regex)
} ?: return@mapNotNull null)
}.toMap()
val classesSubtypes = mutableMapOf<KSClassDeclaration, MutableSet<KSClassDeclaration>>()
resolver.getAllFiles().forEach {
it.declarations.forEach { potentialSubtype ->
if (potentialSubtype is KSClassDeclaration) {
if (
potentialSubtype is KSClassDeclaration
&& potentialSubtype.isAnnotationPresent(ClassCastsExcluded::class).not()
) {
val allSupertypes = potentialSubtype.getAllSuperTypes().map { it.declaration }
classes.forEach {
if (it in allSupertypes) {
classesSubtypes.getOrPut(it) { mutableSetOf() }.add(potentialSubtype)
for (currentClass in classes) {
val regexes = classesRegexes[currentClass]
val simpleName = potentialSubtype.simpleName.getShortName()
when {
currentClass !in allSupertypes
|| regexes ?.first ?.matches(simpleName) == false
|| regexes ?.second ?.matches(simpleName) == true -> continue
else -> {
classesSubtypes.getOrPut(currentClass) { mutableSetOf() }.add(potentialSubtype)
}
}
}
}
}
}
fun fillWithSealeds(source: KSClassDeclaration, current: KSClassDeclaration = source) {
val regexes = classesRegexes[source]
current.getSealedSubclasses().forEach {
val simpleName = it.simpleName.getShortName()
if (
regexes ?.first ?.matches(simpleName) == false
|| regexes ?.second ?.matches(simpleName) == true
|| it.isAnnotationPresent(ClassCastsExcluded::class)
) {
return@forEach
}
classesSubtypes.getOrPut(source) { mutableSetOf() }.add(it)
fillWithSealeds(source, it)
}

View File

@@ -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
@@ -27,25 +28,11 @@ import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.BaseChosenInline
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.ChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.LocationChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultAudioCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultAudioImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultContact
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultDocumentCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultDocumentImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGame
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGifCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGifImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultLocation
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultMpeg4GifCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultMpeg4GifImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultPhotoCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultPhotoImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultStickerCached
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVenue
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVideoCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVideoImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVoiceCachedImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVoiceImpl
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.DescribedInlineQueryResult
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.FileInlineQueryResult
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
@@ -108,6 +95,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
@@ -122,50 +110,37 @@ import dev.inmo.tgbotapi.types.buttons.ReplyKeyboardRemove
import dev.inmo.tgbotapi.types.chat.AbleToAddInAttachmentMenuChat
import dev.inmo.tgbotapi.types.chat.Bot
import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.chat.ChannelChatImpl
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.chat.CommonBot
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.chat.ExtendedBot
import dev.inmo.tgbotapi.types.chat.ExtendedChannelChat
import dev.inmo.tgbotapi.types.chat.ExtendedChannelChatImpl
import dev.inmo.tgbotapi.types.chat.ExtendedChat
import dev.inmo.tgbotapi.types.chat.ExtendedChatWithUsername
import dev.inmo.tgbotapi.types.chat.ExtendedForumChat
import dev.inmo.tgbotapi.types.chat.ExtendedForumChatImpl
import dev.inmo.tgbotapi.types.chat.ExtendedGroupChat
import dev.inmo.tgbotapi.types.chat.ExtendedGroupChatImpl
import dev.inmo.tgbotapi.types.chat.ExtendedPrivateChat
import dev.inmo.tgbotapi.types.chat.ExtendedPrivateChatImpl
import dev.inmo.tgbotapi.types.chat.ExtendedPublicChat
import dev.inmo.tgbotapi.types.chat.ExtendedSupergroupChat
import dev.inmo.tgbotapi.types.chat.ExtendedSupergroupChatImpl
import dev.inmo.tgbotapi.types.chat.ForumChat
import dev.inmo.tgbotapi.types.chat.ForumChatImpl
import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.chat.GroupChatImpl
import dev.inmo.tgbotapi.types.chat.PossiblyPremiumChat
import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.chat.PrivateChatImpl
import dev.inmo.tgbotapi.types.chat.PublicChat
import dev.inmo.tgbotapi.types.chat.SuperPublicChat
import dev.inmo.tgbotapi.types.chat.SupergroupChat
import dev.inmo.tgbotapi.types.chat.SupergroupChatImpl
import dev.inmo.tgbotapi.types.chat.UnknownChatType
import dev.inmo.tgbotapi.types.chat.UnknownExtendedChat
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.UsernameChat
import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember
import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMemberImpl
import dev.inmo.tgbotapi.types.chat.member.BannedChatMember
import dev.inmo.tgbotapi.types.chat.member.ChatMember
import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated
import dev.inmo.tgbotapi.types.chat.member.KickedChatMember
import dev.inmo.tgbotapi.types.chat.member.LeftChatMember
import dev.inmo.tgbotapi.types.chat.member.LeftChatMemberImpl
import dev.inmo.tgbotapi.types.chat.member.MemberChatMember
import dev.inmo.tgbotapi.types.chat.member.MemberChatMemberImpl
import dev.inmo.tgbotapi.types.chat.member.OwnerChatMember
import dev.inmo.tgbotapi.types.chat.member.RestrictedChatMember
import dev.inmo.tgbotapi.types.chat.member.SpecialRightsChatMember
@@ -226,9 +201,6 @@ import dev.inmo.tgbotapi.types.media.TelegramMediaVideo
import dev.inmo.tgbotapi.types.media.ThumbedTelegramMedia
import dev.inmo.tgbotapi.types.media.TitledTelegramMedia
import dev.inmo.tgbotapi.types.media.VisualMediaGroupMemberTelegramMedia
import dev.inmo.tgbotapi.types.message.AnonymousForumContentMessageImpl
import dev.inmo.tgbotapi.types.message.AnonymousGroupContentMessageImpl
import dev.inmo.tgbotapi.types.message.ChannelContentMessageImpl
import dev.inmo.tgbotapi.types.message.ChannelEventMessage
import dev.inmo.tgbotapi.types.message.ChatEvents.ChannelChatCreated
import dev.inmo.tgbotapi.types.message.ChatEvents.DeleteChatPhoto
@@ -264,17 +236,11 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatEnded
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatParticipantsInvited
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatScheduled
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatStarted
import dev.inmo.tgbotapi.types.message.CommonForumContentMessageImpl
import dev.inmo.tgbotapi.types.message.CommonGroupContentMessageImpl
import dev.inmo.tgbotapi.types.message.CommonGroupEventMessage
import dev.inmo.tgbotapi.types.message.CommonSupergroupEventMessage
import dev.inmo.tgbotapi.types.message.ConnectedFromChannelGroupContentMessageImpl
import dev.inmo.tgbotapi.types.message.ForwardInfo
import dev.inmo.tgbotapi.types.message.FromChannelForumContentMessageImpl
import dev.inmo.tgbotapi.types.message.PassportMessage
import dev.inmo.tgbotapi.types.message.PrivateContentMessageImpl
import dev.inmo.tgbotapi.types.message.PrivateEventMessage
import dev.inmo.tgbotapi.types.message.UnconnectedFromChannelGroupContentMessageImpl
import dev.inmo.tgbotapi.types.message.abstracts.AnonymousForumContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.AnonymousGroupContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.ChannelContentMessage
@@ -327,6 +293,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
@@ -632,16 +599,6 @@ public inline fun WithUser.administratorChatMemberOrThrow(): AdministratorChatMe
public inline fun <T> WithUser.ifAdministratorChatMember(block: (AdministratorChatMember) -> T): T?
= administratorChatMemberOrNull() ?.let(block)
public inline fun WithUser.administratorChatMemberImplOrNull(): AdministratorChatMemberImpl? = this
as? dev.inmo.tgbotapi.types.chat.member.AdministratorChatMemberImpl
public inline fun WithUser.administratorChatMemberImplOrThrow(): AdministratorChatMemberImpl = this
as dev.inmo.tgbotapi.types.chat.member.AdministratorChatMemberImpl
public inline fun <T>
WithUser.ifAdministratorChatMemberImpl(block: (AdministratorChatMemberImpl) -> T): T? =
administratorChatMemberImplOrNull() ?.let(block)
public inline fun WithUser.bannedChatMemberOrNull(): BannedChatMember? = this as?
dev.inmo.tgbotapi.types.chat.member.BannedChatMember
@@ -687,15 +644,6 @@ public inline fun WithUser.leftChatMemberOrThrow(): LeftChatMember = this as
public inline fun <T> WithUser.ifLeftChatMember(block: (LeftChatMember) -> T): T? =
leftChatMemberOrNull() ?.let(block)
public inline fun WithUser.leftChatMemberImplOrNull(): LeftChatMemberImpl? = this as?
dev.inmo.tgbotapi.types.chat.member.LeftChatMemberImpl
public inline fun WithUser.leftChatMemberImplOrThrow(): LeftChatMemberImpl = this as
dev.inmo.tgbotapi.types.chat.member.LeftChatMemberImpl
public inline fun <T> WithUser.ifLeftChatMemberImpl(block: (LeftChatMemberImpl) -> T): T? =
leftChatMemberImplOrNull() ?.let(block)
public inline fun WithUser.memberChatMemberOrNull(): MemberChatMember? = this as?
dev.inmo.tgbotapi.types.chat.member.MemberChatMember
@@ -705,15 +653,6 @@ public inline fun WithUser.memberChatMemberOrThrow(): MemberChatMember = this as
public inline fun <T> WithUser.ifMemberChatMember(block: (MemberChatMember) -> T): T? =
memberChatMemberOrNull() ?.let(block)
public inline fun WithUser.memberChatMemberImplOrNull(): MemberChatMemberImpl? = this as?
dev.inmo.tgbotapi.types.chat.member.MemberChatMemberImpl
public inline fun WithUser.memberChatMemberImplOrThrow(): MemberChatMemberImpl = this as
dev.inmo.tgbotapi.types.chat.member.MemberChatMemberImpl
public inline fun <T> WithUser.ifMemberChatMemberImpl(block: (MemberChatMemberImpl) -> T): T? =
memberChatMemberImplOrNull() ?.let(block)
public inline fun WithUser.ownerChatMemberOrNull(): OwnerChatMember? = this as?
dev.inmo.tgbotapi.types.chat.member.OwnerChatMember
@@ -774,30 +713,6 @@ public inline fun <T>
WithUser.ifCommonSupergroupEventMessage(block: (CommonSupergroupEventMessage<SupergroupEvent>) -> T):
T? = commonSupergroupEventMessageOrNull() ?.let(block)
public inline fun WithUser.commonGroupContentMessageImplOrNull():
CommonGroupContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.CommonGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun WithUser.commonGroupContentMessageImplOrThrow():
CommonGroupContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.CommonGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
WithUser.ifCommonGroupContentMessageImpl(block: (CommonGroupContentMessageImpl<MessageContent>) -> T):
T? = commonGroupContentMessageImplOrNull() ?.let(block)
public inline fun WithUser.commonForumContentMessageImplOrNull():
CommonForumContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.CommonForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun WithUser.commonForumContentMessageImplOrThrow():
CommonForumContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.CommonForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
WithUser.ifCommonForumContentMessageImpl(block: (CommonForumContentMessageImpl<MessageContent>) -> T):
T? = commonForumContentMessageImplOrNull() ?.let(block)
public inline fun WithUser.passportMessageOrNull(): PassportMessage? = this as?
dev.inmo.tgbotapi.types.message.PassportMessage
@@ -807,18 +722,6 @@ public inline fun WithUser.passportMessageOrThrow(): PassportMessage = this as
public inline fun <T> WithUser.ifPassportMessage(block: (PassportMessage) -> T): T? =
passportMessageOrNull() ?.let(block)
public inline fun WithUser.privateContentMessageImplOrNull():
PrivateContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.PrivateContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun WithUser.privateContentMessageImplOrThrow():
PrivateContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.PrivateContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
WithUser.ifPrivateContentMessageImpl(block: (PrivateContentMessageImpl<MessageContent>) -> T):
T? = privateContentMessageImplOrNull() ?.let(block)
public inline fun WithUser.fromUserMessageOrNull(): FromUserMessage? = this as?
dev.inmo.tgbotapi.types.message.abstracts.FromUserMessage
@@ -1013,6 +916,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
@@ -1094,28 +1027,6 @@ public inline fun <T>
InlineQueryResult.ifInlineQueryResultArticle(block: (InlineQueryResultArticle) -> T): T? =
inlineQueryResultArticleOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultAudioCachedImplOrNull():
InlineQueryResultAudioCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultAudioCachedImpl
public inline fun InlineQueryResult.inlineQueryResultAudioCachedImplOrThrow():
InlineQueryResultAudioCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultAudioCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultAudioCachedImpl(block: (InlineQueryResultAudioCachedImpl) -> T):
T? = inlineQueryResultAudioCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultAudioImplOrNull(): InlineQueryResultAudioImpl?
= this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultAudioImpl
public inline fun InlineQueryResult.inlineQueryResultAudioImplOrThrow(): InlineQueryResultAudioImpl
= this as dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultAudioImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultAudioImpl(block: (InlineQueryResultAudioImpl) -> T): T? =
inlineQueryResultAudioImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultContactOrNull(): InlineQueryResultContact? =
this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultContact
@@ -1126,30 +1037,6 @@ public inline fun <T>
InlineQueryResult.ifInlineQueryResultContact(block: (InlineQueryResultContact) -> T): T? =
inlineQueryResultContactOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultDocumentCachedImplOrNull():
InlineQueryResultDocumentCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultDocumentCachedImpl
public inline fun InlineQueryResult.inlineQueryResultDocumentCachedImplOrThrow():
InlineQueryResultDocumentCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultDocumentCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultDocumentCachedImpl(block: (InlineQueryResultDocumentCachedImpl) -> T):
T? = inlineQueryResultDocumentCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultDocumentImplOrNull():
InlineQueryResultDocumentImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultDocumentImpl
public inline fun InlineQueryResult.inlineQueryResultDocumentImplOrThrow():
InlineQueryResultDocumentImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultDocumentImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultDocumentImpl(block: (InlineQueryResultDocumentImpl) -> T):
T? = inlineQueryResultDocumentImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultGameOrNull(): InlineQueryResultGame? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGame
@@ -1160,28 +1047,6 @@ public inline fun <T>
InlineQueryResult.ifInlineQueryResultGame(block: (InlineQueryResultGame) -> T): T? =
inlineQueryResultGameOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultGifCachedImplOrNull():
InlineQueryResultGifCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGifCachedImpl
public inline fun InlineQueryResult.inlineQueryResultGifCachedImplOrThrow():
InlineQueryResultGifCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGifCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultGifCachedImpl(block: (InlineQueryResultGifCachedImpl) -> T):
T? = inlineQueryResultGifCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultGifImplOrNull(): InlineQueryResultGifImpl? =
this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGifImpl
public inline fun InlineQueryResult.inlineQueryResultGifImplOrThrow(): InlineQueryResultGifImpl =
this as dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultGifImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultGifImpl(block: (InlineQueryResultGifImpl) -> T): T? =
inlineQueryResultGifImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultLocationOrNull(): InlineQueryResultLocation? =
this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultLocation
@@ -1192,52 +1057,6 @@ public inline fun <T>
InlineQueryResult.ifInlineQueryResultLocation(block: (InlineQueryResultLocation) -> T): T? =
inlineQueryResultLocationOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultMpeg4GifCachedImplOrNull():
InlineQueryResultMpeg4GifCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultMpeg4GifCachedImpl
public inline fun InlineQueryResult.inlineQueryResultMpeg4GifCachedImplOrThrow():
InlineQueryResultMpeg4GifCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultMpeg4GifCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultMpeg4GifCachedImpl(block: (InlineQueryResultMpeg4GifCachedImpl) -> T):
T? = inlineQueryResultMpeg4GifCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultMpeg4GifImplOrNull():
InlineQueryResultMpeg4GifImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultMpeg4GifImpl
public inline fun InlineQueryResult.inlineQueryResultMpeg4GifImplOrThrow():
InlineQueryResultMpeg4GifImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultMpeg4GifImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultMpeg4GifImpl(block: (InlineQueryResultMpeg4GifImpl) -> T):
T? = inlineQueryResultMpeg4GifImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultPhotoCachedImplOrNull():
InlineQueryResultPhotoCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultPhotoCachedImpl
public inline fun InlineQueryResult.inlineQueryResultPhotoCachedImplOrThrow():
InlineQueryResultPhotoCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultPhotoCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultPhotoCachedImpl(block: (InlineQueryResultPhotoCachedImpl) -> T):
T? = inlineQueryResultPhotoCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultPhotoImplOrNull(): InlineQueryResultPhotoImpl?
= this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultPhotoImpl
public inline fun InlineQueryResult.inlineQueryResultPhotoImplOrThrow(): InlineQueryResultPhotoImpl
= this as dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultPhotoImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultPhotoImpl(block: (InlineQueryResultPhotoImpl) -> T): T? =
inlineQueryResultPhotoImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultStickerCachedOrNull():
InlineQueryResultStickerCached? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultStickerCached
@@ -1260,50 +1079,6 @@ public inline fun <T>
InlineQueryResult.ifInlineQueryResultVenue(block: (InlineQueryResultVenue) -> T): T? =
inlineQueryResultVenueOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultVideoCachedImplOrNull():
InlineQueryResultVideoCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVideoCachedImpl
public inline fun InlineQueryResult.inlineQueryResultVideoCachedImplOrThrow():
InlineQueryResultVideoCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVideoCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultVideoCachedImpl(block: (InlineQueryResultVideoCachedImpl) -> T):
T? = inlineQueryResultVideoCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultVideoImplOrNull(): InlineQueryResultVideoImpl?
= this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVideoImpl
public inline fun InlineQueryResult.inlineQueryResultVideoImplOrThrow(): InlineQueryResultVideoImpl
= this as dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVideoImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultVideoImpl(block: (InlineQueryResultVideoImpl) -> T): T? =
inlineQueryResultVideoImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultVoiceCachedImplOrNull():
InlineQueryResultVoiceCachedImpl? = this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVoiceCachedImpl
public inline fun InlineQueryResult.inlineQueryResultVoiceCachedImplOrThrow():
InlineQueryResultVoiceCachedImpl = this as
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVoiceCachedImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultVoiceCachedImpl(block: (InlineQueryResultVoiceCachedImpl) -> T):
T? = inlineQueryResultVoiceCachedImplOrNull() ?.let(block)
public inline fun InlineQueryResult.inlineQueryResultVoiceImplOrNull(): InlineQueryResultVoiceImpl?
= this as? dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVoiceImpl
public inline fun InlineQueryResult.inlineQueryResultVoiceImplOrThrow(): InlineQueryResultVoiceImpl
= this as dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultVoiceImpl
public inline fun <T>
InlineQueryResult.ifInlineQueryResultVoiceImpl(block: (InlineQueryResultVoiceImpl) -> T): T? =
inlineQueryResultVoiceImplOrNull() ?.let(block)
public inline fun InlineQueryResult.describedInlineQueryResultOrNull(): DescribedInlineQueryResult?
= this as?
dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.DescribedInlineQueryResult
@@ -1898,6 +1673,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
@@ -2085,51 +1872,6 @@ public inline fun <T>
Chat.ifAbleToAddInAttachmentMenuChat(block: (AbleToAddInAttachmentMenuChat) -> T): T? =
ableToAddInAttachmentMenuChatOrNull() ?.let(block)
public inline fun Chat.extendedChannelChatImplOrNull(): ExtendedChannelChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ExtendedChannelChatImpl
public inline fun Chat.extendedChannelChatImplOrThrow(): ExtendedChannelChatImpl = this as
dev.inmo.tgbotapi.types.chat.ExtendedChannelChatImpl
public inline fun <T> Chat.ifExtendedChannelChatImpl(block: (ExtendedChannelChatImpl) -> T): T? =
extendedChannelChatImplOrNull() ?.let(block)
public inline fun Chat.extendedGroupChatImplOrNull(): ExtendedGroupChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ExtendedGroupChatImpl
public inline fun Chat.extendedGroupChatImplOrThrow(): ExtendedGroupChatImpl = this as
dev.inmo.tgbotapi.types.chat.ExtendedGroupChatImpl
public inline fun <T> Chat.ifExtendedGroupChatImpl(block: (ExtendedGroupChatImpl) -> T): T? =
extendedGroupChatImplOrNull() ?.let(block)
public inline fun Chat.extendedPrivateChatImplOrNull(): ExtendedPrivateChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ExtendedPrivateChatImpl
public inline fun Chat.extendedPrivateChatImplOrThrow(): ExtendedPrivateChatImpl = this as
dev.inmo.tgbotapi.types.chat.ExtendedPrivateChatImpl
public inline fun <T> Chat.ifExtendedPrivateChatImpl(block: (ExtendedPrivateChatImpl) -> T): T? =
extendedPrivateChatImplOrNull() ?.let(block)
public inline fun Chat.extendedSupergroupChatImplOrNull(): ExtendedSupergroupChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ExtendedSupergroupChatImpl
public inline fun Chat.extendedSupergroupChatImplOrThrow(): ExtendedSupergroupChatImpl = this as
dev.inmo.tgbotapi.types.chat.ExtendedSupergroupChatImpl
public inline fun <T> Chat.ifExtendedSupergroupChatImpl(block: (ExtendedSupergroupChatImpl) -> T):
T? = extendedSupergroupChatImplOrNull() ?.let(block)
public inline fun Chat.extendedForumChatImplOrNull(): ExtendedForumChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ExtendedForumChatImpl
public inline fun Chat.extendedForumChatImplOrThrow(): ExtendedForumChatImpl = this as
dev.inmo.tgbotapi.types.chat.ExtendedForumChatImpl
public inline fun <T> Chat.ifExtendedForumChatImpl(block: (ExtendedForumChatImpl) -> T): T? =
extendedForumChatImplOrNull() ?.let(block)
public inline fun Chat.extendedBotOrNull(): ExtendedBot? = this as?
dev.inmo.tgbotapi.types.chat.ExtendedBot
@@ -2220,51 +1962,6 @@ public inline fun Chat.extendedChatWithUsernameOrThrow(): ExtendedChatWithUserna
public inline fun <T> Chat.ifExtendedChatWithUsername(block: (ExtendedChatWithUsername) -> T): T? =
extendedChatWithUsernameOrNull() ?.let(block)
public inline fun Chat.groupChatImplOrNull(): GroupChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.GroupChatImpl
public inline fun Chat.groupChatImplOrThrow(): GroupChatImpl = this as
dev.inmo.tgbotapi.types.chat.GroupChatImpl
public inline fun <T> Chat.ifGroupChatImpl(block: (GroupChatImpl) -> T): T? = groupChatImplOrNull()
?.let(block)
public inline fun Chat.privateChatImplOrNull(): PrivateChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.PrivateChatImpl
public inline fun Chat.privateChatImplOrThrow(): PrivateChatImpl = this as
dev.inmo.tgbotapi.types.chat.PrivateChatImpl
public inline fun <T> Chat.ifPrivateChatImpl(block: (PrivateChatImpl) -> T): T? =
privateChatImplOrNull() ?.let(block)
public inline fun Chat.supergroupChatImplOrNull(): SupergroupChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.SupergroupChatImpl
public inline fun Chat.supergroupChatImplOrThrow(): SupergroupChatImpl = this as
dev.inmo.tgbotapi.types.chat.SupergroupChatImpl
public inline fun <T> Chat.ifSupergroupChatImpl(block: (SupergroupChatImpl) -> T): T? =
supergroupChatImplOrNull() ?.let(block)
public inline fun Chat.forumChatImplOrNull(): ForumChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ForumChatImpl
public inline fun Chat.forumChatImplOrThrow(): ForumChatImpl = this as
dev.inmo.tgbotapi.types.chat.ForumChatImpl
public inline fun <T> Chat.ifForumChatImpl(block: (ForumChatImpl) -> T): T? = forumChatImplOrNull()
?.let(block)
public inline fun Chat.channelChatImplOrNull(): ChannelChatImpl? = this as?
dev.inmo.tgbotapi.types.chat.ChannelChatImpl
public inline fun Chat.channelChatImplOrThrow(): ChannelChatImpl = this as
dev.inmo.tgbotapi.types.chat.ChannelChatImpl
public inline fun <T> Chat.ifChannelChatImpl(block: (ChannelChatImpl) -> T): T? =
channelChatImplOrNull() ?.let(block)
public inline fun Chat.userOrNull(): User? = this as? dev.inmo.tgbotapi.types.chat.User
public inline fun Chat.userOrThrow(): User = this as dev.inmo.tgbotapi.types.chat.User
@@ -3195,18 +2892,6 @@ public inline fun <T>
ForwardInfo.ifSentByChannel(block: (ForwardInfo.PublicChat.SentByChannel) -> T): T? =
sentByChannelOrNull() ?.let(block)
public inline fun Message.channelContentMessageImplOrNull():
ChannelContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.ChannelContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.channelContentMessageImplOrThrow():
ChannelContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.ChannelContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifChannelContentMessageImpl(block: (ChannelContentMessageImpl<MessageContent>) -> T): T?
= channelContentMessageImplOrNull() ?.let(block)
public inline fun Message.channelEventMessageOrNull(): ChannelEventMessage<ChannelEvent>? = this as?
dev.inmo.tgbotapi.types.message.ChannelEventMessage<dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent>
@@ -3241,90 +2926,6 @@ public inline fun <T>
Message.ifCommonSupergroupEventMessage(block: (CommonSupergroupEventMessage<SupergroupEvent>) -> T):
T? = commonSupergroupEventMessageOrNull() ?.let(block)
public inline fun Message.connectedFromChannelGroupContentMessageImplOrNull():
ConnectedFromChannelGroupContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.ConnectedFromChannelGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.connectedFromChannelGroupContentMessageImplOrThrow():
ConnectedFromChannelGroupContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.ConnectedFromChannelGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifConnectedFromChannelGroupContentMessageImpl(block: (ConnectedFromChannelGroupContentMessageImpl<MessageContent>) -> T):
T? = connectedFromChannelGroupContentMessageImplOrNull() ?.let(block)
public inline fun Message.unconnectedFromChannelGroupContentMessageImplOrNull():
UnconnectedFromChannelGroupContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.UnconnectedFromChannelGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.unconnectedFromChannelGroupContentMessageImplOrThrow():
UnconnectedFromChannelGroupContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.UnconnectedFromChannelGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifUnconnectedFromChannelGroupContentMessageImpl(block: (UnconnectedFromChannelGroupContentMessageImpl<MessageContent>) -> T):
T? = unconnectedFromChannelGroupContentMessageImplOrNull() ?.let(block)
public inline fun Message.anonymousGroupContentMessageImplOrNull():
AnonymousGroupContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.AnonymousGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.anonymousGroupContentMessageImplOrThrow():
AnonymousGroupContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.AnonymousGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifAnonymousGroupContentMessageImpl(block: (AnonymousGroupContentMessageImpl<MessageContent>) -> T):
T? = anonymousGroupContentMessageImplOrNull() ?.let(block)
public inline fun Message.commonGroupContentMessageImplOrNull():
CommonGroupContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.CommonGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.commonGroupContentMessageImplOrThrow():
CommonGroupContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.CommonGroupContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifCommonGroupContentMessageImpl(block: (CommonGroupContentMessageImpl<MessageContent>) -> T):
T? = commonGroupContentMessageImplOrNull() ?.let(block)
public inline fun Message.fromChannelForumContentMessageImplOrNull():
FromChannelForumContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.FromChannelForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.fromChannelForumContentMessageImplOrThrow():
FromChannelForumContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.FromChannelForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifFromChannelForumContentMessageImpl(block: (FromChannelForumContentMessageImpl<MessageContent>) -> T):
T? = fromChannelForumContentMessageImplOrNull() ?.let(block)
public inline fun Message.anonymousForumContentMessageImplOrNull():
AnonymousForumContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.AnonymousForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.anonymousForumContentMessageImplOrThrow():
AnonymousForumContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.AnonymousForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifAnonymousForumContentMessageImpl(block: (AnonymousForumContentMessageImpl<MessageContent>) -> T):
T? = anonymousForumContentMessageImplOrNull() ?.let(block)
public inline fun Message.commonForumContentMessageImplOrNull():
CommonForumContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.CommonForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.commonForumContentMessageImplOrThrow():
CommonForumContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.CommonForumContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifCommonForumContentMessageImpl(block: (CommonForumContentMessageImpl<MessageContent>) -> T):
T? = commonForumContentMessageImplOrNull() ?.let(block)
public inline fun Message.passportMessageOrNull(): PassportMessage? = this as?
dev.inmo.tgbotapi.types.message.PassportMessage
@@ -3334,18 +2935,6 @@ public inline fun Message.passportMessageOrThrow(): PassportMessage = this as
public inline fun <T> Message.ifPassportMessage(block: (PassportMessage) -> T): T? =
passportMessageOrNull() ?.let(block)
public inline fun Message.privateContentMessageImplOrNull():
PrivateContentMessageImpl<MessageContent>? = this as?
dev.inmo.tgbotapi.types.message.PrivateContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun Message.privateContentMessageImplOrThrow():
PrivateContentMessageImpl<MessageContent> = this as
dev.inmo.tgbotapi.types.message.PrivateContentMessageImpl<dev.inmo.tgbotapi.types.message.content.MessageContent>
public inline fun <T>
Message.ifPrivateContentMessageImpl(block: (PrivateContentMessageImpl<MessageContent>) -> T): T?
= privateContentMessageImplOrNull() ?.let(block)
public inline fun Message.privateEventMessageOrNull(): PrivateEventMessage<PrivateEvent>? = this as?
dev.inmo.tgbotapi.types.message.PrivateEventMessage<dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent>
@@ -3668,6 +3257,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

View File

@@ -3,17 +3,60 @@ package dev.inmo.tgbotapi.extensions.utils.extensions
import dev.inmo.tgbotapi.abstracts.FromUser
import dev.inmo.tgbotapi.abstracts.WithUser
import dev.inmo.tgbotapi.extensions.utils.asUser
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.BaseChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.ChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.LocationChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.query.BaseInlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.query.LocationInlineQuery
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
import dev.inmo.tgbotapi.types.queries.callback.*
import dev.inmo.tgbotapi.types.update.*
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.PreviewFeature
fun CallbackQuery.sourceChat() = when (this) {
is InlineMessageIdDataCallbackQuery -> null
is MessageDataCallbackQuery -> message.chat
is InlineMessageIdGameShortNameCallbackQuery -> null
is MessageGameShortNameCallbackQuery -> message.chat
is UnknownCallbackQueryType -> null
}
@PreviewFeature
fun Update.sourceChat(): Chat? = when (this) {
is BaseMessageUpdate -> data.chat
is ChatJoinRequestUpdate -> data.chat
fun Update.sourceChatWithConverters(
baseMessageUpdateConverter: (BaseMessageUpdate) -> Chat? = { it.data.chat },
chatJoinRequestUpdateConverter: (ChatJoinRequestUpdate) -> Chat? = { it.data.chat },
shippingQueryUpdateConverter: (ShippingQueryUpdate) -> Chat? = { null },
pollAnswerUpdateConverter: (PollAnswerUpdate) -> Chat? = { null },
preCheckoutQueryUpdateConverter: (PreCheckoutQueryUpdate) -> Chat? = { it.data.from },
callbackQueryUpdateConverter: (CallbackQueryUpdate) -> Chat? = { it.data.sourceChat() },
chosenInlineResultUpdateConverter: (ChosenInlineResultUpdate) -> Chat? = { null },
inlineQueryUpdateConverter: (InlineQueryUpdate) -> Chat? = { null },
pollUpdateConverter: (PollUpdate) -> Chat? = { null },
channelPostUpdateConverter: (ChannelPostUpdate) -> Chat? = { it.data.chat },
messageUpdateConverter: (MessageUpdate) -> Chat? = { it.data.chat },
editChannelPostUpdateConverter: (EditChannelPostUpdate) -> Chat? = { it.data.chat },
editMessageUpdateConverter: (EditMessageUpdate) -> Chat? = { it.data.chat },
myChatMemberUpdatedUpdateConverter: (MyChatMemberUpdatedUpdate) -> Chat? = { it.data.chat },
commonChatMemberUpdatedUpdateConverter: (CommonChatMemberUpdatedUpdate) -> Chat? = { it.data.chat }
): Chat? = when (this) {
is BaseMessageUpdate -> baseMessageUpdateConverter(this)
is ChatJoinRequestUpdate -> chatJoinRequestUpdateConverter(this)
is ShippingQueryUpdate -> shippingQueryUpdateConverter(this)
is PollAnswerUpdate -> pollAnswerUpdateConverter(this)
is PreCheckoutQueryUpdate -> preCheckoutQueryUpdateConverter(this)
is CallbackQueryUpdate -> callbackQueryUpdateConverter(this)
is ChosenInlineResultUpdate -> chosenInlineResultUpdateConverter(this)
is InlineQueryUpdate -> inlineQueryUpdateConverter(this)
is PollUpdate -> pollUpdateConverter(this)
is ChannelPostUpdate -> channelPostUpdateConverter(this)
is MessageUpdate -> messageUpdateConverter(this)
is EditChannelPostUpdate -> editChannelPostUpdateConverter(this)
is EditMessageUpdate -> editMessageUpdateConverter(this)
is MyChatMemberUpdatedUpdate -> myChatMemberUpdatedUpdateConverter(this)
is CommonChatMemberUpdatedUpdate -> commonChatMemberUpdatedUpdateConverter(this)
else -> {
when (val data = data) {
is FromUser -> data.from
@@ -23,6 +66,9 @@ fun Update.sourceChat(): Chat? = when (this) {
}
}
@PreviewFeature
fun Update.sourceChat(): Chat? = sourceChatWithConverters()
@PreviewFeature
fun Update.sourceUser(): User? = when (val data = data) {
is FromUser -> data.from

Some files were not shown because too many files have changed in this diff Show More