mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2026-05-31 20:57:24 +00:00
Compare commits
21 Commits
0.38.21
...
8331d4edd7
| Author | SHA1 | Date | |
|---|---|---|---|
| 8331d4edd7 | |||
| 0e6a708eea | |||
| fbc5e9f8c4 | |||
| 040a996df6 | |||
| cf27600fb5 | |||
| 1d42f86623 | |||
| a9cb07fa0d | |||
| dd7567f43c | |||
| d0006bb089 | |||
| 7d8b990ec4 | |||
| 4d20e2cd1c | |||
| 4ffe6f915f | |||
| 22a7697447 | |||
| ef9941134e | |||
| ba85b8657d | |||
| 2dcbc0df32 | |||
| 7bac4a3a32 | |||
| 63bcc4bcf8 | |||
| 643f8e577e | |||
| 721b82f912 | |||
| 892aef738d |
60
CHANGELOG.md
60
CHANGELOG.md
@@ -1,63 +1,19 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
## 0.38.21
|
## 1.0.0
|
||||||
|
|
||||||
* `WebApps`:
|
|
||||||
* `WebAppInitData#queryId` now have correct js name of field
|
|
||||||
* New function `sendDataOrWorkWithQueryId`
|
|
||||||
|
|
||||||
## 0.38.20
|
|
||||||
|
|
||||||
* `BehaviourBuilder FSM`:
|
|
||||||
* Hotfixes
|
|
||||||
* `WebApps`:
|
|
||||||
* New extension `TelegramBot#answerWebAppQuery`
|
|
||||||
* New function `handleResult`
|
|
||||||
|
|
||||||
## 0.38.19
|
|
||||||
|
|
||||||
* `BehaviourBuilder`:
|
|
||||||
* Hotfixes
|
|
||||||
* `BehaviourBuilder FSM`:
|
|
||||||
* `BehaviourContextWithFSMBuilder` deprecated in favor to `BehaviourContextWithFSM`
|
|
||||||
* Now it is possible to define additional handlers in subcontexts of `BehaviourBuilderWithFSM`
|
|
||||||
|
|
||||||
## 0.38.18
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* Add support of test servers (fix of [#577](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/577))
|
|
||||||
* `BehaviourBuilder`:
|
|
||||||
* Fixes in extension `BehaviourContext#doInSubContextWithUpdatesFilter` (thanks to [xzima](https://github.com/xzima))
|
|
||||||
|
|
||||||
## 0.38.17
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* Add `BotCommandScopeChat` as new `BotCommandScope` (fix of [#574](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/574))
|
|
||||||
* `BotCommandScope` companion got several properties and functions for more useful scope creation
|
|
||||||
|
|
||||||
## 0.38.16
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* `TelegramAPIUrlsKeeper` now have two new things: properties `webAppDataSecretKey` and fun `checkWebAppLink`
|
|
||||||
|
|
||||||
## 0.38.15
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.9.20` -> `0.9.24`
|
|
||||||
* `Core`:
|
|
||||||
* Fixes in `MessageContent#serializationModule`
|
|
||||||
* `BehaviourBuilder`:
|
|
||||||
* Add triggers for `DataCallbackQuery` and subtypes with regex checking of data
|
|
||||||
|
|
||||||
## 0.38.14
|
|
||||||
|
|
||||||
__This update contains including of [Telegram Bot API 6.0](https://core.telegram.org/bots/api-changelog#april-16-2022)__
|
__This update contains including of [Telegram Bot API 6.0](https://core.telegram.org/bots/api-changelog#april-16-2022)__
|
||||||
|
|
||||||
|
__All the `tgbotapi.extensions.*` packages have been removed__
|
||||||
|
|
||||||
* `Core`:
|
* `Core`:
|
||||||
* Constructor of `UnknownInlineKeyboardButton` is not internal and can be created with any `json`
|
* Constructor of `UnknownInlineKeyboardButton` is not internal and can be created with any `json` ([#563](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/563))
|
||||||
|
* All the interfaces from `dev.inmo.tgbotapi.types.files.abstracts` have been replaced to `dev.inmo.tgbotapi.types.files` and converted to sealed ([#550](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/550))
|
||||||
|
* `PassportFile` has been replaced to `dev.inmo.tgbotapi.types.files`
|
||||||
* `WebApps`:
|
* `WebApps`:
|
||||||
* Created 🎉
|
* Created 🎉
|
||||||
|
* `BehaviourBuilder`:
|
||||||
|
* `SimpleFilter` now is a `fun interface` instead of just callback (fix of [#546](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/546))
|
||||||
|
|
||||||
## 0.38.13
|
## 0.38.13
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ klock_version=2.7.0
|
|||||||
uuid_version=0.4.0
|
uuid_version=0.4.0
|
||||||
ktor_version=1.6.8
|
ktor_version=1.6.8
|
||||||
|
|
||||||
micro_utils_version=0.9.24
|
micro_utils_version=0.9.20
|
||||||
|
|
||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
@@ -20,6 +20,6 @@ javax_activation_version=1.1.1
|
|||||||
dokka_version=1.6.10
|
dokka_version=1.6.10
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.38.21
|
library_version=1.0.0
|
||||||
|
|
||||||
github_release_plugin_version=2.3.7
|
github_release_plugin_version=2.3.7
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ include ":tgbotapi.api"
|
|||||||
include ":tgbotapi.utils"
|
include ":tgbotapi.utils"
|
||||||
include ":tgbotapi.behaviour_builder"
|
include ":tgbotapi.behaviour_builder"
|
||||||
include ":tgbotapi.behaviour_builder.fsm"
|
include ":tgbotapi.behaviour_builder.fsm"
|
||||||
include ":tgbotapi.extensions.api"
|
|
||||||
include ":tgbotapi.extensions.utils"
|
|
||||||
include ":tgbotapi.extensions.behaviour_builder"
|
|
||||||
include ":tgbotapi.extensions.behaviour_builder.fsm"
|
|
||||||
include ":tgbotapi"
|
include ":tgbotapi"
|
||||||
include ":tgbotapi.webapps"
|
include ":tgbotapi.webapps"
|
||||||
include ":docs"
|
include ":docs"
|
||||||
|
|||||||
@@ -40,9 +40,8 @@ data class BotBuilder internal constructor(
|
|||||||
fun buildBot(
|
fun buildBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
testServer: Boolean = false,
|
|
||||||
block: BotBuilder.() -> Unit
|
block: BotBuilder.() -> Unit
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||||
BotBuilder().apply(block).createHttpClient()
|
BotBuilder().apply(block).createHttpClient()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import io.ktor.client.engine.*
|
|||||||
*/
|
*/
|
||||||
fun telegramBot(
|
fun telegramBot(
|
||||||
urlsKeeper: TelegramAPIUrlsKeeper,
|
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
client: HttpClient = HttpClient()
|
client: HttpClient
|
||||||
): TelegramBot = telegramBot(urlsKeeper) {
|
): TelegramBot = telegramBot(urlsKeeper) {
|
||||||
this.client = client
|
this.client = client
|
||||||
}
|
}
|
||||||
@@ -66,19 +66,17 @@ inline fun telegramBot(
|
|||||||
inline fun telegramBot(
|
inline fun telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
testServer: Boolean = false,
|
client: HttpClient
|
||||||
client: HttpClient = HttpClient()
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client)
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, testServer, apiUrl), client)
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <T: HttpClientEngineConfig> telegramBot(
|
inline fun <T: HttpClientEngineConfig> telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
clientFactory: HttpClientEngineFactory<T>,
|
clientFactory: HttpClientEngineFactory<T>,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
testServer: Boolean = false,
|
|
||||||
noinline clientConfig: HttpClientConfig<T>.() -> Unit = {}
|
noinline clientConfig: HttpClientConfig<T>.() -> Unit = {}
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||||
clientFactory,
|
clientFactory,
|
||||||
clientConfig
|
clientConfig
|
||||||
)
|
)
|
||||||
@@ -92,10 +90,9 @@ inline fun telegramBot(
|
|||||||
token: String,
|
token: String,
|
||||||
clientEngine: HttpClientEngine,
|
clientEngine: HttpClientEngine,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
testServer: Boolean = false,
|
|
||||||
noinline clientConfig: HttpClientConfig<*>.() -> Unit = {}
|
noinline clientConfig: HttpClientConfig<*>.() -> Unit = {}
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||||
clientEngine,
|
clientEngine,
|
||||||
clientConfig
|
clientConfig
|
||||||
)
|
)
|
||||||
@@ -108,9 +105,8 @@ inline fun telegramBot(
|
|||||||
inline fun telegramBot(
|
inline fun telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
testServer: Boolean = false,
|
|
||||||
noinline clientConfig: HttpClientConfig<*>.() -> Unit
|
noinline clientConfig: HttpClientConfig<*>.() -> Unit
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||||
clientConfig
|
clientConfig
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
|||||||
import dev.inmo.tgbotapi.requests.DownloadFile
|
import dev.inmo.tgbotapi.requests.DownloadFile
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.files.PathedFile
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
|
||||||
suspend fun TelegramBot.downloadFile(
|
suspend fun TelegramBot.downloadFile(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.inmo.tgbotapi.bot.TelegramBot
|
|||||||
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.files.PathedFile
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
|
||||||
suspend fun TelegramBot.downloadFileStream(
|
suspend fun TelegramBot.downloadFileStream(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
|||||||
import dev.inmo.tgbotapi.requests.DownloadFileStream
|
import dev.inmo.tgbotapi.requests.DownloadFileStream
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.files.PathedFile
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
|
||||||
suspend fun TelegramBot.downloadFileStreamAllocator(
|
suspend fun TelegramBot.downloadFileStreamAllocator(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.get
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.get.GetFile
|
import dev.inmo.tgbotapi.requests.get.GetFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
|
||||||
suspend fun TelegramBot.getFileAdditionalInfo(
|
suspend fun TelegramBot.getFileAdditionalInfo(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.extensions.api.get
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.get.GetStickerSet
|
import dev.inmo.tgbotapi.requests.get.GetStickerSet
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
|
|
||||||
suspend fun TelegramBot.getStickerSet(
|
suspend fun TelegramBot.getStickerSet(
|
||||||
name: String
|
name: String
|
||||||
|
|||||||
@@ -18,12 +18,11 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
|||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.dice.DiceAnimationType
|
import dev.inmo.tgbotapi.types.dice.DiceAnimationType
|
||||||
import dev.inmo.tgbotapi.types.files.*
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
import dev.inmo.tgbotapi.types.games.Game
|
import dev.inmo.tgbotapi.types.games.Game
|
||||||
import dev.inmo.tgbotapi.types.location.*
|
import dev.inmo.tgbotapi.types.location.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||||
import dev.inmo.tgbotapi.types.message.content.*
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.ChatIdentifier
|
|||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.stickers
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.stickers.DeleteStickerFromSet
|
import dev.inmo.tgbotapi.requests.stickers.DeleteStickerFromSet
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
|
|
||||||
suspend fun TelegramBot.deleteStickerFromSet(
|
suspend fun TelegramBot.deleteStickerFromSet(
|
||||||
sticker: FileId
|
sticker: FileId
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.stickers
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.stickers.SetStickerPositionInSet
|
import dev.inmo.tgbotapi.requests.stickers.SetStickerPositionInSet
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
|
|
||||||
suspend fun TelegramBot.setStickerPositionInSet(
|
suspend fun TelegramBot.setStickerPositionInSet(
|
||||||
sticker: FileId,
|
sticker: FileId,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.bot.TelegramBot
|
|||||||
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.files.PathedFile
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import io.ktor.util.cio.use
|
import io.ktor.util.cio.use
|
||||||
import io.ktor.util.cio.writeChannel
|
import io.ktor.util.cio.writeChannel
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import dev.inmo.micro_utils.coroutines.accumulatorFlow
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have
|
* Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have
|
||||||
@@ -28,31 +26,10 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
|
|||||||
handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
|
handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
|
||||||
): T? {
|
): T? {
|
||||||
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
|
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
|
||||||
doInSubContext(updatesUpstreamFlow = contextUpdatesFlow) {
|
handleState(contextUpdatesFlow, state)
|
||||||
handleState(state)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
|
||||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
|
||||||
*
|
|
||||||
* @see BehaviourWithFSMStateHandlerHolder
|
|
||||||
* @see onStateOrSubstate
|
|
||||||
*/
|
|
||||||
fun <I : T> add(kClass: KClass<I>, strict: Boolean = false, handler: BehaviourWithFSMStateHandler<I, T>)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
|
||||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
|
||||||
* requirements
|
|
||||||
*
|
|
||||||
* @see BehaviourWithFSMStateHandlerHolder
|
|
||||||
* @see strictlyOn
|
|
||||||
*/
|
|
||||||
fun <I : T> addStrict(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) = add(kClass, strict = true, handler)
|
|
||||||
|
|
||||||
override fun copy(
|
override fun copy(
|
||||||
bot: TelegramBot,
|
bot: TelegramBot,
|
||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
@@ -71,28 +48,6 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
|
||||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
|
||||||
*
|
|
||||||
* @see BehaviourWithFSMStateHandlerHolder
|
|
||||||
* @see BehaviourContextWithFSM.add
|
|
||||||
*/
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
inline fun <reified I : O, O: State> BehaviourContextWithFSM<O>.onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, O>) = add(I::class, strict = false, handler)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
|
||||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
|
||||||
* requirements
|
|
||||||
*
|
|
||||||
* @see BehaviourWithFSMStateHandlerHolder
|
|
||||||
* @see BehaviourContextWithFSM.addStrict
|
|
||||||
*/
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
inline fun <reified I : O, O: State> BehaviourContextWithFSM<O>.strictlyOn(handler: BehaviourWithFSMStateHandler<I, O>) = addStrict(I::class, handler)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as
|
* Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as
|
||||||
* [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states
|
* [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states
|
||||||
@@ -103,9 +58,6 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
|||||||
private val handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
|
private val handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
|
||||||
) : BehaviourContext by behaviourContext, BehaviourContextWithFSM<T> {
|
) : BehaviourContext by behaviourContext, BehaviourContextWithFSM<T> {
|
||||||
private val updatesFlows = mutableMapOf<Any, Flow<Update>>()
|
private val updatesFlows = mutableMapOf<Any, Flow<Update>>()
|
||||||
private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>()
|
|
||||||
private var actualHandlersList = additionalHandlers + handlers
|
|
||||||
|
|
||||||
private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) {
|
private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) {
|
||||||
allUpdatesFlow.accumulatorFlow(scope)
|
allUpdatesFlow.accumulatorFlow(scope)
|
||||||
}
|
}
|
||||||
@@ -113,17 +65,12 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
|||||||
override suspend fun StatesMachine<in T>.handleState(state: T): T? = launchStateHandling(
|
override suspend fun StatesMachine<in T>.handleState(state: T): T? = launchStateHandling(
|
||||||
state,
|
state,
|
||||||
allUpdatesFlow,
|
allUpdatesFlow,
|
||||||
actualHandlersList
|
handlers
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun <I : T> add(kClass: KClass<I>, strict: Boolean, handler: BehaviourWithFSMStateHandler<I, T>) {
|
|
||||||
additionalHandlers.add(BehaviourWithFSMStateHandlerHolder(kClass, strict, handler))
|
|
||||||
actualHandlersList = additionalHandlers + handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
|
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
|
||||||
val statePerformer: suspend (T) -> Unit = { state: T ->
|
val statePerformer: suspend (T) -> Unit = { state: T ->
|
||||||
val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), actualHandlersList)
|
val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers)
|
||||||
if (newState != null) {
|
if (newState != null) {
|
||||||
statesManager.update(state, newState)
|
statesManager.update(state, newState)
|
||||||
} else {
|
} else {
|
||||||
@@ -147,26 +94,6 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
|||||||
launch { statePerformer(it) }
|
launch { statePerformer(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
|
||||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
|
||||||
*
|
|
||||||
* @see BehaviourWithFSMStateHandlerHolder
|
|
||||||
* @see BehaviourContextWithFSM.add
|
|
||||||
*/
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
inline fun <reified I : T> onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, T>) = add(I::class, strict = false, handler)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
|
||||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
|
||||||
* requirements
|
|
||||||
*
|
|
||||||
* @see BehaviourWithFSMStateHandlerHolder
|
|
||||||
* @see BehaviourContextWithFSM.addStrict
|
|
||||||
*/
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
inline fun <reified I : T> strictlyOn(handler: BehaviourWithFSMStateHandler<I, T>) = addStrict(I::class, handler)
|
|
||||||
|
|
||||||
override suspend fun startChain(state: T) {
|
override suspend fun startChain(state: T) {
|
||||||
statesManager.startChain(state)
|
statesManager.startChain(state)
|
||||||
@@ -179,7 +106,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
|||||||
onBufferOverflow: BufferOverflow,
|
onBufferOverflow: BufferOverflow,
|
||||||
upstreamUpdatesFlow: Flow<Update>?,
|
upstreamUpdatesFlow: Flow<Update>?,
|
||||||
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
||||||
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
): BehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
||||||
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter),
|
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter),
|
||||||
handlers,
|
handlers,
|
||||||
statesManager
|
statesManager
|
||||||
|
|||||||
@@ -14,8 +14,70 @@ import kotlinx.coroutines.*
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@Deprecated("Will be removed soon")
|
class BehaviourContextWithFSMBuilder<T : State> internal constructor(
|
||||||
typealias BehaviourContextWithFSMBuilder<T> = BehaviourContextWithFSM<T>
|
private val resultBehaviourContext: BehaviourContextWithFSM<T>,
|
||||||
|
private val handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>>
|
||||||
|
) : BehaviourContextWithFSM<T> by resultBehaviourContext {
|
||||||
|
internal constructor(
|
||||||
|
baseBehaviourContext: BehaviourContext,
|
||||||
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
|
handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf()
|
||||||
|
) : this(DefaultBehaviourContextWithFSM(baseBehaviourContext, statesManager, handlers), handlers)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||||
|
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||||
|
*
|
||||||
|
* @see BehaviourWithFSMStateHandlerHolder
|
||||||
|
* @see onStateOrSubstate
|
||||||
|
*/
|
||||||
|
fun <I : T> add(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||||
|
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, false, handler))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||||
|
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||||
|
* requirements
|
||||||
|
*
|
||||||
|
* @see BehaviourWithFSMStateHandlerHolder
|
||||||
|
* @see strictlyOn
|
||||||
|
*/
|
||||||
|
fun <I : T> addStrict(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||||
|
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, true, handler))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||||
|
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||||
|
*
|
||||||
|
* @see BehaviourWithFSMStateHandlerHolder
|
||||||
|
* @see BehaviourContextWithFSMBuilder.add
|
||||||
|
*/
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
inline fun <reified I : T> onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||||
|
add(I::class, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||||
|
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||||
|
* requirements
|
||||||
|
*
|
||||||
|
* @see BehaviourWithFSMStateHandlerHolder
|
||||||
|
* @see BehaviourContextWithFSMBuilder.addStrict
|
||||||
|
*/
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
inline fun <reified I : T> strictlyOn(handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||||
|
addStrict(I::class, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns completed [resultBehaviourContext], [handlers] and [statesManager]
|
||||||
|
*/
|
||||||
|
internal fun build() = resultBehaviourContext
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates [BehaviourContextWithFSM] via creating of [DefaultBehaviourContext] with [this] as [TelegramBot],
|
* Creates [BehaviourContextWithFSM] via creating of [DefaultBehaviourContext] with [this] as [TelegramBot],
|
||||||
@@ -32,17 +94,17 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
|||||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
): BehaviourContextWithFSM<T> = BehaviourContextWithFSMBuilder(
|
||||||
DefaultBehaviourContext(
|
DefaultBehaviourContext(
|
||||||
this,
|
this,
|
||||||
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
|
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
|
||||||
upstreamUpdatesFlow = upstreamUpdatesFlow
|
upstreamUpdatesFlow = upstreamUpdatesFlow
|
||||||
),
|
),
|
||||||
presetHandlers,
|
statesManager,
|
||||||
statesManager
|
presetHandlers
|
||||||
).apply { block() }
|
).apply { block() }.build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates
|
* Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates
|
||||||
@@ -54,9 +116,9 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
|||||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
): Pair<BehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
||||||
upstreamUpdatesFlow,
|
upstreamUpdatesFlow,
|
||||||
scope,
|
scope,
|
||||||
defaultExceptionsHandler,
|
defaultExceptionsHandler,
|
||||||
@@ -85,8 +147,8 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
|||||||
* @see BehaviourContext
|
* @see BehaviourContext
|
||||||
* @see BehaviourContextWithFSM
|
* @see BehaviourContextWithFSM
|
||||||
* @see longPolling
|
* @see longPolling
|
||||||
* @see BehaviourContextWithFSM.strictlyOn
|
* @see BehaviourContextWithFSMBuilder.strictlyOn
|
||||||
* @see BehaviourContextWithFSM.onStateOrSubstate
|
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate
|
||||||
*/
|
*/
|
||||||
@PreviewFeature
|
@PreviewFeature
|
||||||
suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
||||||
@@ -94,17 +156,17 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
|||||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
): BehaviourContextWithFSM<T> = BehaviourContextWithFSMBuilder(
|
||||||
DefaultBehaviourContext(
|
DefaultBehaviourContext(
|
||||||
this,
|
this,
|
||||||
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
|
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
|
||||||
upstreamUpdatesFlow = flowUpdatesFilter.allUpdatesFlow
|
upstreamUpdatesFlow = flowUpdatesFilter.allUpdatesFlow
|
||||||
),
|
),
|
||||||
presetHandlers,
|
statesManager,
|
||||||
statesManager
|
presetHandlers
|
||||||
).apply { block() }
|
).apply { block() }.build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates
|
* Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates
|
||||||
@@ -114,16 +176,16 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
|||||||
* @see buildBehaviourWithFSMAndStartLongPolling
|
* @see buildBehaviourWithFSMAndStartLongPolling
|
||||||
* @see BehaviourContext
|
* @see BehaviourContext
|
||||||
* @see longPolling
|
* @see longPolling
|
||||||
* @see BehaviourContextWithFSM.strictlyOn
|
* @see BehaviourContextWithFSMBuilder.strictlyOn
|
||||||
* @see BehaviourContextWithFSM.onStateOrSubstate
|
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate
|
||||||
*/
|
*/
|
||||||
@PreviewFeature
|
@PreviewFeature
|
||||||
suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
) = FlowsUpdatesFilter().let {
|
) = FlowsUpdatesFilter().let {
|
||||||
buildBehaviourWithFSM(
|
buildBehaviourWithFSM(
|
||||||
it,
|
it,
|
||||||
|
|||||||
@@ -34,11 +34,20 @@ class BehaviourWithFSMStateHandlerHolder<I : O, O : State>(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handling of state :)
|
* Handling of state :)
|
||||||
|
*
|
||||||
|
* @param contextUpdatesFlow This [Flow] will be used as source of updates. By contract, this [Flow] must be common
|
||||||
|
* for all [State]s of incoming [state] [State.context] and for the whole chain inside of [BehaviourContextWithFSM]
|
||||||
*/
|
*/
|
||||||
suspend fun BehaviourContextWithFSM<in O>.handleState(
|
suspend fun BehaviourContextWithFSM<in O>.handleState(
|
||||||
|
contextUpdatesFlow: Flow<Update>,
|
||||||
state: O
|
state: O
|
||||||
): O? = with(delegateTo) {
|
): O? {
|
||||||
handleState(state as I)
|
val subscope = scope.LinkedSupervisorScope()
|
||||||
|
return with(copy(scope = subscope, upstreamUpdatesFlow = contextUpdatesFlow)) {
|
||||||
|
with(delegateTo) {
|
||||||
|
handleState(state as I)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,11 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
|||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
testServer: Boolean = false,
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
|
||||||
): TelegramBot = telegramBot(
|
): TelegramBot = telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
testServer,
|
|
||||||
builder
|
builder
|
||||||
).apply {
|
).apply {
|
||||||
buildBehaviourWithFSMAndStartLongPolling(
|
buildBehaviourWithFSMAndStartLongPolling(
|
||||||
@@ -74,14 +72,12 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
|||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
testServer: Boolean = false,
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
|
||||||
): Pair<TelegramBot, Job> {
|
): Pair<TelegramBot, Job> {
|
||||||
return telegramBot(
|
return telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
testServer,
|
|
||||||
builder
|
builder
|
||||||
).let {
|
).let {
|
||||||
it to it.buildBehaviourWithFSMAndStartLongPolling (
|
it to it.buildBehaviourWithFSMAndStartLongPolling (
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ internal inline fun <BC, T, I1, I2> CustomBehaviourContextAndTwoTypesReceiver<BC
|
|||||||
): CustomBehaviourContextAndTypeReceiver<BC, T, I2> = { invoke(this, i1, it) }
|
): CustomBehaviourContextAndTypeReceiver<BC, T, I2> = { invoke(this, i1, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains all necessary tools for work with bots and especially [buildBehaviour]
|
* This class contains all necessary tools for work with bots and especially for [buildBehaviour]
|
||||||
*
|
*
|
||||||
* @see DefaultBehaviourContext
|
* @see DefaultBehaviourContext
|
||||||
*/
|
*/
|
||||||
@@ -90,7 +90,7 @@ class DefaultBehaviourContext(
|
|||||||
onBufferOverflow: BufferOverflow,
|
onBufferOverflow: BufferOverflow,
|
||||||
upstreamUpdatesFlow: Flow<Update>?,
|
upstreamUpdatesFlow: Flow<Update>?,
|
||||||
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
||||||
): DefaultBehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter)
|
): BehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BehaviourContext(
|
fun BehaviourContext(
|
||||||
@@ -116,20 +116,19 @@ suspend fun <T, BC : BehaviourContext> BC.doInSubContextWithUpdatesFilter(
|
|||||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
||||||
scope: CoroutineScope = LinkedSupervisorScope(),
|
scope: CoroutineScope = LinkedSupervisorScope(),
|
||||||
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
||||||
): T {
|
): T = copy(
|
||||||
val newContext = copy(
|
scope = scope,
|
||||||
scope = scope,
|
updatesFilter = updatesFilter ?.let { _ ->
|
||||||
updatesFilter = updatesFilter ?.let { _ ->
|
{
|
||||||
{
|
(this as? BC) ?.run {
|
||||||
(this as? BC) ?.run {
|
updatesFilter(it)
|
||||||
updatesFilter(it)
|
} ?: true
|
||||||
} ?: true
|
}
|
||||||
}
|
},
|
||||||
},
|
upstreamUpdatesFlow = updatesUpstreamFlow
|
||||||
upstreamUpdatesFlow = updatesUpstreamFlow
|
).run {
|
||||||
) as BC
|
withContext(coroutineContext) {
|
||||||
return withContext(currentCoroutineContext()) {
|
behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
||||||
newContext.behaviourContextReceiver().also { if (stopOnCompletion) newContext.stop() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,10 @@ suspend fun telegramBotWithBehaviour(
|
|||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
testServer: Boolean = false,
|
|
||||||
block: BehaviourContextReceiver<Unit>
|
block: BehaviourContextReceiver<Unit>
|
||||||
): TelegramBot = telegramBot(
|
): TelegramBot = telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
testServer,
|
|
||||||
builder
|
builder
|
||||||
).apply {
|
).apply {
|
||||||
buildBehaviour(
|
buildBehaviour(
|
||||||
@@ -65,13 +63,11 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
|||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
testServer: Boolean = false,
|
|
||||||
block: BehaviourContextReceiver<Unit>
|
block: BehaviourContextReceiver<Unit>
|
||||||
): Pair<TelegramBot, Job> {
|
): Pair<TelegramBot, Job> {
|
||||||
return telegramBot(
|
return telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
testServer,
|
|
||||||
builder
|
builder
|
||||||
).let {
|
).let {
|
||||||
it to it.buildBehaviourWithLongPolling(
|
it to it.buildBehaviourWithLongPolling(
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ private suspend inline fun <reified T : CallbackQuery> BehaviourContext.waitCall
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<T>? = null,
|
filter: SimpleFilter<T>? = null,
|
||||||
noinline mapper: CallbackQueryMapper<T>? = null
|
noinline mapper: CallbackQueryMapper<T>? = null
|
||||||
) : List<T> = waitCallbackQueries<T>(
|
) : List<T> = waitCallbackQueries<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ private suspend inline fun <reified T : ChatMemberUpdatedUpdate> BehaviourContex
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<T>? = null,
|
filter: SimpleFilter<T>? = null,
|
||||||
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>
|
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>
|
||||||
): List<ChatMemberUpdated> = expectFlow(
|
): List<ChatMemberUpdated> = expectFlow(
|
||||||
initRequest,
|
initRequest,
|
||||||
@@ -34,7 +34,7 @@ private suspend inline fun <reified T : ChatMemberUpdatedUpdate> BehaviourContex
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<T>? = null,
|
filter: SimpleFilter<T>? = null,
|
||||||
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
|
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
|
||||||
) : List<ChatMemberUpdated> = waitChatMemberUpdated<T>(
|
) : List<ChatMemberUpdated> = waitChatMemberUpdated<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ private suspend inline fun <reified T : ChosenInlineResult> BehaviourContext.wai
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<T>? = null,
|
filter: SimpleFilter<T>? = null,
|
||||||
noinline mapper: ChosenInlineResultMapper<T>? = null
|
noinline mapper: ChosenInlineResultMapper<T>? = null
|
||||||
) : List<T> = this@waitChosenInlineResults.waitChosenInlineResultsUpdates<T>(
|
) : List<T> = this@waitChosenInlineResults.waitChosenInlineResultsUpdates<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<CommonMessage<T>>? = null,
|
filter: SimpleFilter<CommonMessage<T>>? = null,
|
||||||
noinline mapper: CommonMessageToContentMapper<T>? = null
|
noinline mapper: CommonMessageToContentMapper<T>? = null
|
||||||
) : List<T> = waitCommonContent<T>(
|
) : List<T> = waitCommonContent<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<CommonMessage<T>>? = null,
|
filter: SimpleFilter<CommonMessage<T>>? = null,
|
||||||
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
|
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
|
||||||
) : List<CommonMessage<T>> = waitCommonMessage<T>(
|
) : List<CommonMessage<T>> = waitCommonMessage<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitEdi
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<CommonMessage<T>>? = null,
|
filter: SimpleFilter<CommonMessage<T>>? = null,
|
||||||
noinline mapper: CommonMessageToContentMapper<T>? = null
|
noinline mapper: CommonMessageToContentMapper<T>? = null
|
||||||
) : List<T> = waitEditedCommonMessage<T>(
|
) : List<T> = waitEditedCommonMessage<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ private suspend inline fun <reified T : ChatEvent> BehaviourContext.waitEvents(
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<ChatEventMessage<T>>? = null,
|
filter: SimpleFilter<ChatEventMessage<T>>? = null,
|
||||||
noinline mapper: EventMessageToEventMapper<T>? = null
|
noinline mapper: EventMessageToEventMapper<T>? = null
|
||||||
) : List<T> = waitEventMessages<T>(
|
) : List<T> = waitEventMessages<T>(
|
||||||
initRequest,
|
initRequest,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ private suspend inline fun <reified T : InlineQuery> BehaviourContext.waitInline
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<T>? = null,
|
filter: SimpleFilter<T>? = null,
|
||||||
noinline mapper: InlineQueryMapper<T>? = null
|
noinline mapper: InlineQueryMapper<T>? = null
|
||||||
) : List<T> = waitInlineQueries<T>(
|
) : List<T> = waitInlineQueries<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ suspend inline fun <reified T : EncryptedPassportElement> BehaviourContext.waitP
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<PassportMessage>? = null,
|
filter: SimpleFilter<PassportMessage>? = null,
|
||||||
noinline mapper: PassportMessageMapper? = null
|
noinline mapper: PassportMessageMapper? = null
|
||||||
) : List<PassportData> = waitPassportMessages(
|
) : List<PassportData> = waitPassportMessages(
|
||||||
initRequest,
|
initRequest,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ private suspend inline fun BehaviourContext.waitPollAnswers(
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<PollAnswer>? = null,
|
filter: SimpleFilter<PollAnswer>? = null,
|
||||||
noinline mapper: PollAnswerMapper? = null
|
noinline mapper: PollAnswerMapper? = null
|
||||||
) : List<PollAnswer> = this@waitPollAnswers.waitPollsAnswers<PollAnswer>(
|
) : List<PollAnswer> = this@waitPollAnswers.waitPollsAnswers<PollAnswer>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ private suspend inline fun <reified T : Poll> BehaviourContext.waitPolls(
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<T>? = null,
|
filter: SimpleFilter<T>? = null,
|
||||||
noinline mapper: PollMapper<T>? = null
|
noinline mapper: PollMapper<T>? = null
|
||||||
) : List<T> = this@waitPolls.waitPollsUpdates<T>(
|
) : List<T> = this@waitPolls.waitPollsUpdates<T>(
|
||||||
count,
|
count,
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.filters
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.CommonMessageFilter
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.CommonMessageFilter
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,6 +17,6 @@ val MessageFilterExcludingMediaGroups: BehaviourContextAndTwoTypesReceiver<Boole
|
|||||||
/**
|
/**
|
||||||
* Allow only messages which are not [MediaGroupMessage]
|
* Allow only messages which are not [MediaGroupMessage]
|
||||||
*/
|
*/
|
||||||
val CommonMessageFilterExcludeMediaGroups: CommonMessageFilter<*> = {
|
val CommonMessageFilterExcludeMediaGroups = SimpleFilter<Message> {
|
||||||
it !is MediaGroupMessage<*>
|
it !is MediaGroupMessage<*>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CallbackQueryFilte
|
|||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserCallbackQueryMarkerFactory
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserCallbackQueryMarkerFactory
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate
|
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate
|
||||||
import dev.inmo.tgbotapi.types.CallbackQuery.*
|
import dev.inmo.tgbotapi.types.CallbackQuery.*
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : CallbackQuery> BC.onCallbackQuery(
|
internal suspend inline fun <BC : BehaviourContext, reified T : CallbackQuery> BC.onCallbackQuery(
|
||||||
noinline initialFilter: SimpleFilter<T>? = null,
|
initialFilter: SimpleFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = CallbackQueryFilterByUser,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = CallbackQueryFilterByUser,
|
||||||
markerFactory: MarkerFactory<in T, Any> = ByUserCallbackQueryMarkerFactory,
|
markerFactory: MarkerFactory<in T, Any> = ByUserCallbackQueryMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
||||||
@@ -45,62 +44,6 @@ suspend fun <BC : BehaviourContext> BC.onDataCallbackQuery(
|
|||||||
scenarioReceiver
|
scenarioReceiver
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
|
||||||
* @param dataRegex Will be used with [initialFilter] as [initialFilter] for upstream [onDataCallbackQuery] to filter
|
|
||||||
* [DataCallbackQuery] with [DataCallbackQuery.data] [String.matches] to [dataRegex]
|
|
||||||
* @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.onDataCallbackQuery(
|
|
||||||
dataRegex: Regex,
|
|
||||||
initialFilter: SimpleFilter<DataCallbackQuery>? = null,
|
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DataCallbackQuery, Update>? = CallbackQueryFilterByUser,
|
|
||||||
markerFactory: MarkerFactory<in DataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
|
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DataCallbackQuery>
|
|
||||||
) = onDataCallbackQuery(
|
|
||||||
initialFilter = initialFilter + {
|
|
||||||
it.data.matches(dataRegex)
|
|
||||||
},
|
|
||||||
subcontextUpdatesFilter,
|
|
||||||
markerFactory,
|
|
||||||
scenarioReceiver
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Will be converted to [Regex] via its constructor and pass it to upstream [onDataCallbackQuery]
|
|
||||||
* @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.onDataCallbackQuery(
|
|
||||||
data: String,
|
|
||||||
initialFilter: SimpleFilter<DataCallbackQuery>? = null,
|
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DataCallbackQuery, Update>? = CallbackQueryFilterByUser,
|
|
||||||
markerFactory: MarkerFactory<in DataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
|
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DataCallbackQuery>
|
|
||||||
) = onDataCallbackQuery(
|
|
||||||
Regex(data),
|
|
||||||
initialFilter,
|
|
||||||
subcontextUpdatesFilter,
|
|
||||||
markerFactory,
|
|
||||||
scenarioReceiver
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
@@ -173,62 +116,6 @@ suspend fun <BC : BehaviourContext> BC.onInlineMessageIdDataCallbackQuery(
|
|||||||
scenarioReceiver
|
scenarioReceiver
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
|
||||||
* @param dataRegex Will be used with [initialFilter] as [initialFilter] for upstream [onInlineMessageIdDataCallbackQuery]
|
|
||||||
* to filter [InlineMessageIdDataCallbackQuery] with [InlineMessageIdDataCallbackQuery.data] [String.matches] to [dataRegex]
|
|
||||||
* @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.onInlineMessageIdDataCallbackQuery(
|
|
||||||
dataRegex: Regex,
|
|
||||||
initialFilter: SimpleFilter<InlineMessageIdDataCallbackQuery>? = null,
|
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InlineMessageIdDataCallbackQuery, Update>? = CallbackQueryFilterByUser,
|
|
||||||
markerFactory: MarkerFactory<in InlineMessageIdDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
|
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InlineMessageIdDataCallbackQuery>
|
|
||||||
) = onInlineMessageIdDataCallbackQuery(
|
|
||||||
initialFilter = initialFilter + {
|
|
||||||
it.data.matches(dataRegex)
|
|
||||||
},
|
|
||||||
subcontextUpdatesFilter,
|
|
||||||
markerFactory,
|
|
||||||
scenarioReceiver
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Will be converted to [Regex] via its constructor and pass it to upstream [onInlineMessageIdDataCallbackQuery]
|
|
||||||
* @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.onInlineMessageIdDataCallbackQuery(
|
|
||||||
data: String,
|
|
||||||
initialFilter: SimpleFilter<InlineMessageIdDataCallbackQuery>? = null,
|
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InlineMessageIdDataCallbackQuery, Update>? = CallbackQueryFilterByUser,
|
|
||||||
markerFactory: MarkerFactory<in InlineMessageIdDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
|
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InlineMessageIdDataCallbackQuery>
|
|
||||||
) = onInlineMessageIdDataCallbackQuery(
|
|
||||||
Regex(data),
|
|
||||||
initialFilter,
|
|
||||||
subcontextUpdatesFilter,
|
|
||||||
markerFactory,
|
|
||||||
scenarioReceiver
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
@@ -301,62 +188,6 @@ suspend fun <BC : BehaviourContext> BC.onMessageDataCallbackQuery(
|
|||||||
scenarioReceiver
|
scenarioReceiver
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
|
||||||
* @param dataRegex Will be used with [initialFilter] as [initialFilter] for upstream [onMessageDataCallbackQuery] to filter
|
|
||||||
* [MessageDataCallbackQuery] with [MessageDataCallbackQuery.data] [String.matches] to [dataRegex]
|
|
||||||
* @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.onMessageDataCallbackQuery(
|
|
||||||
dataRegex: Regex,
|
|
||||||
initialFilter: SimpleFilter<MessageDataCallbackQuery>? = null,
|
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MessageDataCallbackQuery, Update>? = CallbackQueryFilterByUser,
|
|
||||||
markerFactory: MarkerFactory<in MessageDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
|
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MessageDataCallbackQuery>
|
|
||||||
) = onMessageDataCallbackQuery(
|
|
||||||
initialFilter = initialFilter + {
|
|
||||||
it.data.matches(dataRegex)
|
|
||||||
},
|
|
||||||
subcontextUpdatesFilter,
|
|
||||||
markerFactory,
|
|
||||||
scenarioReceiver
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Will be converted to [Regex] via its constructor and pass it to upstream [onMessageDataCallbackQuery]
|
|
||||||
* @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.onMessageDataCallbackQuery(
|
|
||||||
data: String,
|
|
||||||
initialFilter: SimpleFilter<MessageDataCallbackQuery>? = null,
|
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MessageDataCallbackQuery, Update>? = CallbackQueryFilterByUser,
|
|
||||||
markerFactory: MarkerFactory<in MessageDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
|
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MessageDataCallbackQuery>
|
|
||||||
) = onMessageDataCallbackQuery(
|
|
||||||
Regex(data),
|
|
||||||
initialFilter,
|
|
||||||
subcontextUpdatesFilter,
|
|
||||||
markerFactory,
|
|
||||||
scenarioReceiver
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified U : ChatMemberUpdatedUpdate> BC.onChatMemberUpdatedInternal(
|
internal suspend inline fun <BC : BehaviourContext, reified U : ChatMemberUpdatedUpdate> BC.onChatMemberUpdatedInternal(
|
||||||
noinline initialFilter: SimpleFilter<ChatMemberUpdated>? = null,
|
initialFilter: SimpleFilter<ChatMemberUpdated>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatMemberUpdated, Update>? = ChatMemberUpdatedFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatMemberUpdated, Update>? = ChatMemberUpdatedFilterByChat,
|
||||||
markerFactory: MarkerFactory<ChatMemberUpdated, Any> = ByChatChatMemberUpdatedMarkerFactory,
|
markerFactory: MarkerFactory<ChatMemberUpdated, Any> = ByChatChatMemberUpdatedMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatMemberUpdated>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatMemberUpdated>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import dev.inmo.tgbotapi.types.polls.*
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : ChosenInlineResult> BC.onChosenInlineResultBase(
|
internal suspend inline fun <BC : BehaviourContext, reified T : ChosenInlineResult> BC.onChosenInlineResultBase(
|
||||||
noinline initialFilter: SimpleFilter<T>? = null,
|
initialFilter: SimpleFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null,
|
||||||
markerFactory: MarkerFactory<in T, Any> = ByUserIdChosenInlineResultMarkerFactory,
|
markerFactory: MarkerFactory<in T, Any> = ByUserIdChosenInlineResultMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ suspend fun <BC : BehaviourContext> BC.command(
|
|||||||
suspend inline fun <BC : BehaviourContext> BC.onCommand(
|
suspend inline fun <BC : BehaviourContext> BC.onCommand(
|
||||||
commandRegex: Regex,
|
commandRegex: Regex,
|
||||||
requireOnlyCommandInMessage: Boolean = true,
|
requireOnlyCommandInMessage: Boolean = true,
|
||||||
noinline initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
||||||
@@ -64,7 +64,7 @@ suspend inline fun <BC : BehaviourContext> BC.onCommand(
|
|||||||
suspend inline fun <BC : BehaviourContext> BC.onCommand(
|
suspend inline fun <BC : BehaviourContext> BC.onCommand(
|
||||||
command: String,
|
command: String,
|
||||||
requireOnlyCommandInMessage: Boolean = true,
|
requireOnlyCommandInMessage: Boolean = true,
|
||||||
noinline initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
||||||
@@ -106,7 +106,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
|
|||||||
|
|
||||||
suspend inline fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
suspend inline fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
||||||
commandRegex: Regex,
|
commandRegex: Regex,
|
||||||
noinline initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>>
|
||||||
@@ -114,7 +114,7 @@ suspend inline fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
|||||||
|
|
||||||
suspend inline fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
suspend inline fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
||||||
command: String,
|
command: String,
|
||||||
noinline initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
|
|||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||||
import dev.inmo.tgbotapi.extensions.utils.whenCommonMessage
|
import dev.inmo.tgbotapi.extensions.utils.whenCommonMessage
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.*
|
import dev.inmo.tgbotapi.types.message.content.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
@@ -22,10 +22,9 @@ import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
typealias CommonMessageFilter<T> = SimpleFilter<CommonMessage<T>>
|
typealias CommonMessageFilter<T> = SimpleFilter<CommonMessage<T>>
|
||||||
inline fun <T : MessageContent> CommonMessageFilter(noinline block: CommonMessageFilter<T>) = block
|
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onContentMessageWithType(
|
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onContentMessageWithType(
|
||||||
noinline initialFilter: CommonMessageFilter<T>? = null,
|
initialFilter: CommonMessageFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByC
|
|||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||||
import dev.inmo.tgbotapi.extensions.utils.asEditMessageUpdate
|
import dev.inmo.tgbotapi.extensions.utils.asEditMessageUpdate
|
||||||
import dev.inmo.tgbotapi.extensions.utils.withContent
|
import dev.inmo.tgbotapi.extensions.utils.withContent
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.*
|
import dev.inmo.tgbotapi.types.message.content.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
@@ -36,7 +36,7 @@ import dev.inmo.tgbotapi.utils.PreviewFeature
|
|||||||
|
|
||||||
@PreviewFeature
|
@PreviewFeature
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onEditedContent(
|
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onEditedContent(
|
||||||
noinline initialFilter: CommonMessageFilter<T>? = null,
|
initialFilter: CommonMessageFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : ChatEvent> BC.onEvent(
|
internal suspend inline fun <BC : BehaviourContext, reified T : ChatEvent> BC.onEvent(
|
||||||
noinline initialFilter: SimpleFilter<ChatEventMessage<T>>? = null,
|
initialFilter: SimpleFilter<ChatEventMessage<T>>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<T>, Update>? = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<T>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in ChatEventMessage<T>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<T>, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<T>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<T>>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import dev.inmo.tgbotapi.types.InlineQueries.query.*
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : InlineQuery> BC.onInlineQuery(
|
internal suspend inline fun <BC : BehaviourContext, reified T : InlineQuery> BC.onInlineQuery(
|
||||||
noinline initialFilter: SimpleFilter<T>? = null,
|
initialFilter: SimpleFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = InlineQueryFilterByUser,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = InlineQueryFilterByUser,
|
||||||
markerFactory: MarkerFactory<in T, Any> = ByUserInlineQueryMarkerFactory,
|
markerFactory: MarkerFactory<in T, Any> = ByUserInlineQueryMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
|
|||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T> BC.on(
|
internal suspend inline fun <BC : BehaviourContext, reified T> BC.on(
|
||||||
markerFactory: MarkerFactory<in T, Any>,
|
markerFactory: MarkerFactory<in T, Any>,
|
||||||
noinline initialFilter: SimpleFilter<T>? = null,
|
initialFilter: SimpleFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>,
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>,
|
||||||
noinline updateToData: (Update) -> List<T>?
|
noinline updateToData: (Update) -> List<T>?
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import dev.inmo.tgbotapi.utils.PreviewFeature
|
|||||||
|
|
||||||
@PreviewFeature
|
@PreviewFeature
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : MediaGroupContent> BC.buildMediaGroupTrigger(
|
internal suspend inline fun <BC : BehaviourContext, reified T : MediaGroupContent> BC.buildMediaGroupTrigger(
|
||||||
noinline initialFilter: SimpleFilter<List<MediaGroupMessage<T>>>? = null,
|
initialFilter: SimpleFilter<List<MediaGroupMessage<T>>>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, List<MediaGroupMessage<T>>, Update>? = MessagesFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, List<MediaGroupMessage<T>>, Update>? = MessagesFilterByChat,
|
||||||
markerFactory: MarkerFactory<in List<MediaGroupMessage<T>>, Any> = ByChatMediaGroupMarkerFactory,
|
markerFactory: MarkerFactory<in List<MediaGroupMessage<T>>, Any> = ByChatMediaGroupMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, List<MediaGroupMessage<T>>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, List<MediaGroupMessage<T>>>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportEle
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : EncryptedPassportElement> BC.onPassportMessageWith(
|
internal suspend inline fun <BC : BehaviourContext, reified T : EncryptedPassportElement> BC.onPassportMessageWith(
|
||||||
noinline initialFilter: SimpleFilter<PassportMessage>? = null,
|
initialFilter: SimpleFilter<PassportMessage>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PassportMessage, Update>? = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PassportMessage, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in PassportMessage, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in PassportMessage, Any> = ByChatMessageMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PassportMessage>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PassportMessage>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import dev.inmo.tgbotapi.types.polls.*
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext> BC.onPollAnswered(
|
internal suspend inline fun <BC : BehaviourContext> BC.onPollAnswered(
|
||||||
noinline initialFilter: SimpleFilter<PollAnswer>? = null,
|
initialFilter: SimpleFilter<PollAnswer>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollAnswer, Update>? = null,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollAnswer, Update>? = null,
|
||||||
markerFactory: MarkerFactory<in PollAnswer, Any> = ByIdPollAnswerMarkerFactory,
|
markerFactory: MarkerFactory<in PollAnswer, Any> = ByIdPollAnswerMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollAnswer>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollAnswer>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import dev.inmo.tgbotapi.types.polls.*
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : Poll> BC.onPollUpdatedBase(
|
internal suspend inline fun <BC : BehaviourContext, reified T : Poll> BC.onPollUpdatedBase(
|
||||||
noinline initialFilter: SimpleFilter<T>? = null,
|
initialFilter: SimpleFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null,
|
||||||
markerFactory: MarkerFactory<in T, Any> = ByIdPollMarkerFactory,
|
markerFactory: MarkerFactory<in T, Any> = ByIdPollMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils
|
||||||
|
|
||||||
typealias SimpleFilter<T> = suspend (T) -> Boolean
|
fun interface SimpleFilter<in T> {
|
||||||
|
suspend operator fun invoke(o: T): Boolean
|
||||||
inline fun <T> SimpleFilter(noinline block: SimpleFilter<T>) = block
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return [SimpleFilter] which will return true in case when all the items in incoming data passed [this] filter
|
* @return [SimpleFilter] which will return true in case when all the items in incoming data passed [this] filter
|
||||||
@@ -28,24 +28,20 @@ fun <T> SimpleFilter<T>.listNone() = SimpleFilter<Iterable<T>> {
|
|||||||
/**
|
/**
|
||||||
* Makes an AND (&&) operation between [this] and [other]
|
* Makes an AND (&&) operation between [this] and [other]
|
||||||
*/
|
*/
|
||||||
operator fun <T> SimpleFilter<T>?.times(other: SimpleFilter<T>): SimpleFilter<T> = this ?.let {
|
operator fun <T> SimpleFilter<T>.times(other: SimpleFilter<T>) = SimpleFilter<T> {
|
||||||
{
|
this(it) && other(it)
|
||||||
this(it) && other(it)
|
}
|
||||||
}
|
|
||||||
} ?: other
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes an OR (||) operation between [this] and [other]
|
* Makes an OR (||) operation between [this] and [other]
|
||||||
*/
|
*/
|
||||||
operator fun <T> SimpleFilter<T>?.plus(other: SimpleFilter<T>): SimpleFilter<T> = this ?.let {
|
operator fun <T> SimpleFilter<T>.plus(other: SimpleFilter<T>) = SimpleFilter<T> {
|
||||||
{
|
this(it) || other(it)
|
||||||
this(it) || other(it)
|
}
|
||||||
}
|
|
||||||
} ?: other
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse results of [this]
|
* Reverse results of [this]
|
||||||
*/
|
*/
|
||||||
operator fun <T> SimpleFilter<T>.not(): SimpleFilter<T> = {
|
operator fun <T> SimpleFilter<T>.not() = SimpleFilter<T> {
|
||||||
!this(it)
|
!this(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('test-common')
|
implementation kotlin('test-common')
|
||||||
implementation kotlin('test-annotations-common')
|
implementation kotlin('test-annotations-common')
|
||||||
implementation project(":tgbotapi.extensions.utils")
|
implementation project(":tgbotapi.utils")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,33 @@ import io.ktor.client.features.*
|
|||||||
import io.ktor.client.statement.readText
|
import io.ktor.client.statement.readText
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
class KtorRequestsExecutorBuilder(
|
||||||
|
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
||||||
|
) {
|
||||||
|
var client: HttpClient = HttpClient()
|
||||||
|
var callsFactories: List<KtorCallFactory> = emptyList()
|
||||||
|
var excludeDefaultFactories: Boolean = false
|
||||||
|
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
||||||
|
var jsonFormatter: Json = nonstrictJsonFormat
|
||||||
|
|
||||||
|
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun telegramBot(
|
||||||
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||||
|
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for [telegramBot]
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun telegramBot(
|
||||||
|
token: String,
|
||||||
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||||
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
||||||
|
|
||||||
@RiskFeature
|
@RiskFeature
|
||||||
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
|
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
|
||||||
SimpleRequestCallFactory(),
|
SimpleRequestCallFactory(),
|
||||||
@@ -100,31 +127,3 @@ class KtorRequestsExecutor(
|
|||||||
client.close()
|
client.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class KtorRequestsExecutorBuilder(
|
|
||||||
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
|
||||||
) {
|
|
||||||
var client: HttpClient = HttpClient()
|
|
||||||
var callsFactories: List<KtorCallFactory> = emptyList()
|
|
||||||
var excludeDefaultFactories: Boolean = false
|
|
||||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
|
||||||
var jsonFormatter: Json = nonstrictJsonFormat
|
|
||||||
|
|
||||||
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun telegramBot(
|
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
|
||||||
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shortcut for [telegramBot]
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
inline fun telegramBot(
|
|
||||||
token: String,
|
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
|
||||||
testServer: Boolean = false,
|
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, testServer, apiUrl), builder)
|
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQ
|
|||||||
import dev.inmo.tgbotapi.types.webapps.query.SentWebAppMessage
|
import dev.inmo.tgbotapi.types.webapps.query.SentWebAppMessage
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
/**
|
|
||||||
* @param webAppQueryId [dev.inmo.tgbotapi.webapps.WebAppInitData.queryId]
|
|
||||||
*/
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class AnswerWebAppQuery(
|
data class AnswerWebAppQuery(
|
||||||
@SerialName(webAppQueryIdField)
|
@SerialName(webAppQueryIdField)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package dev.inmo.tgbotapi.requests.get
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.fileIdField
|
||||||
import dev.inmo.tgbotapi.types.files.PathedFile
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.fileIdField
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|||||||
@@ -192,6 +192,13 @@ const val requestContactField = "request_contact"
|
|||||||
const val requestLocationField = "request_location"
|
const val requestLocationField = "request_location"
|
||||||
const val requestPollField = "request_poll"
|
const val requestPollField = "request_poll"
|
||||||
|
|
||||||
|
const val fileNameField = "file_name"
|
||||||
|
const val mimeTypeField = "mime_type"
|
||||||
|
const val fileIdField = "file_id"
|
||||||
|
const val fileSizeField = "file_size"
|
||||||
|
const val fileDateField = "file_date"
|
||||||
|
const val filePathField = "file_path"
|
||||||
|
|
||||||
|
|
||||||
const val requestWriteAccessField = "request_write_access"
|
const val requestWriteAccessField = "request_write_access"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.mimeTypeField
|
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
|||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.mimeTypeField
|
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
|||||||
@@ -22,14 +22,11 @@ private class SurrogateBotCommandScope(
|
|||||||
BotCommandScopeAllGroupChats.type -> BotCommandScopeAllGroupChats
|
BotCommandScopeAllGroupChats.type -> BotCommandScopeAllGroupChats
|
||||||
BotCommandScopeAllChatAdministrators.type -> BotCommandScopeAllChatAdministrators
|
BotCommandScopeAllChatAdministrators.type -> BotCommandScopeAllChatAdministrators
|
||||||
BotCommandScopeChatAdministrators.type -> BotCommandScopeChatAdministrators(
|
BotCommandScopeChatAdministrators.type -> BotCommandScopeChatAdministrators(
|
||||||
chatId ?: error("${BotCommandScopeChatAdministrators.type} type must have $chatIdField field, but have no")
|
chatId ?: error("chat_administrators type must have $chatIdField field, but have no")
|
||||||
)
|
)
|
||||||
BotCommandScopeChatMember.type -> BotCommandScopeChatMember(
|
BotCommandScopeChatMember.type -> BotCommandScopeChatMember(
|
||||||
chatId ?: error("${BotCommandScopeChatMember.type} type must have $chatIdField field, but have no"),
|
chatId ?: error("chat_administrators type must have $chatIdField field, but have no"),
|
||||||
userId ?: error("${BotCommandScopeChatMember.type} type must have $userIdField field, but have no")
|
userId ?: error("chat_administrators type must have $userIdField field, but have no")
|
||||||
)
|
|
||||||
BotCommandScopeChat.type -> BotCommandScopeChat(
|
|
||||||
chatId ?: error("${BotCommandScopeChat.type} type must have $chatIdField field, but have no")
|
|
||||||
)
|
)
|
||||||
else -> UnknownBotCommandScope(type)
|
else -> UnknownBotCommandScope(type)
|
||||||
}
|
}
|
||||||
@@ -43,7 +40,6 @@ private class SurrogateBotCommandScope(
|
|||||||
BotCommandScopeAllChatAdministrators -> SurrogateBotCommandScope(scope.type)
|
BotCommandScopeAllChatAdministrators -> SurrogateBotCommandScope(scope.type)
|
||||||
is BotCommandScopeChatAdministrators -> SurrogateBotCommandScope(scope.type, scope.chatId)
|
is BotCommandScopeChatAdministrators -> SurrogateBotCommandScope(scope.type, scope.chatId)
|
||||||
is BotCommandScopeChatMember -> SurrogateBotCommandScope(scope.type, scope.chatId, scope.userId)
|
is BotCommandScopeChatMember -> SurrogateBotCommandScope(scope.type, scope.chatId, scope.userId)
|
||||||
is BotCommandScopeChat -> SurrogateBotCommandScope(scope.type, scope.chatId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,16 +47,6 @@ private class SurrogateBotCommandScope(
|
|||||||
@Serializable(BotCommandScopeSerializer::class)
|
@Serializable(BotCommandScopeSerializer::class)
|
||||||
sealed interface BotCommandScope {
|
sealed interface BotCommandScope {
|
||||||
val type: String
|
val type: String
|
||||||
|
|
||||||
companion object {
|
|
||||||
val Default = BotCommandScopeDefault
|
|
||||||
val AllPrivateChats = BotCommandScopeAllPrivateChats
|
|
||||||
val AllGroupChats = BotCommandScopeAllGroupChats
|
|
||||||
val AllChatAdministrators = BotCommandScopeAllChatAdministrators
|
|
||||||
fun ChatAdministrators(chatId: ChatIdentifier) = BotCommandScopeChatAdministrators(chatId)
|
|
||||||
fun Chat(chatId: ChatIdentifier) = BotCommandScopeChat(chatId)
|
|
||||||
fun ChatMember(chatId: ChatIdentifier, userId: UserId) = BotCommandScopeChatMember(chatId, userId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -108,17 +94,6 @@ data class BotCommandScopeChatAdministrators(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class BotCommandScopeChat(
|
|
||||||
override val chatId: ChatIdentifier
|
|
||||||
) : ChatBotCommandScope {
|
|
||||||
@Required
|
|
||||||
override val type: String = BotCommandScopeChat.type
|
|
||||||
companion object {
|
|
||||||
const val type = "chat"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BotCommandScopeChatMember(
|
data class BotCommandScopeChatMember(
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package dev.inmo.tgbotapi.types.files
|
|||||||
import dev.inmo.tgbotapi.CommonAbstracts.Performerable
|
import dev.inmo.tgbotapi.CommonAbstracts.Performerable
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
sealed interface CustomNamedMediaFile {
|
||||||
|
val fileName: String?
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.MimeTyped
|
||||||
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
|
sealed interface MimedMediaFile : TelegramMediaFile, MimeTyped
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This object represents a file uploaded to Telegram Passport. Currently all Telegram Passport files are in JPEG format
|
||||||
|
* when decrypted and don't exceed 10MB.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class PassportFile(
|
||||||
|
@SerialName(fileIdField)
|
||||||
|
override val fileId: FileId,
|
||||||
|
@SerialName(fileUniqueIdField)
|
||||||
|
override val fileUniqueId: FileUniqueId,
|
||||||
|
@SerialName(fileDateField)
|
||||||
|
val uploadingDate: TelegramDate,
|
||||||
|
@SerialName(fileSizeField)
|
||||||
|
override val fileSize: Long? = null
|
||||||
|
) : TelegramMediaFile
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
|
sealed interface PlayableMediaFile : TelegramMediaFile {
|
||||||
|
val duration: Long?
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
|
sealed interface SizedMediaFile : TelegramMediaFile {
|
||||||
|
val width: Int
|
||||||
|
val height: Int
|
||||||
|
}
|
||||||
@@ -1,6 +1,156 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
@Deprecated("Replaced", ReplaceWith("Sticker", "dev.inmo.tgbotapi.types.files.sticker.Sticker"))
|
@Serializable
|
||||||
typealias Sticker = Sticker
|
@RiskFeature("This class is used for serialization/deserialization of Sticker interface")
|
||||||
|
data class StickerSurrogate(
|
||||||
|
val file_id: FileId,
|
||||||
|
val file_unique_id: FileUniqueId,
|
||||||
|
val width: Int,
|
||||||
|
val height: Int,
|
||||||
|
val is_animated: Boolean? = null,
|
||||||
|
val is_video: Boolean? = null,
|
||||||
|
val thumb: PhotoSize? = null,
|
||||||
|
val emoji: String? = null,
|
||||||
|
val set_name: StickerSetName? = null,
|
||||||
|
val mask_position: MaskPosition? = null,
|
||||||
|
val file_size: Long? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO:: Serializer
|
||||||
|
@Serializable(StickerSerializer::class)
|
||||||
|
sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile {
|
||||||
|
val emoji: String?
|
||||||
|
val maskPosition: MaskPosition?
|
||||||
|
val stickerSetName: StickerSetName?
|
||||||
|
|
||||||
|
val isAnimated
|
||||||
|
get() = this is AnimatedSticker
|
||||||
|
val isVideo
|
||||||
|
get() = this is VideoSticker
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun serializer(): KSerializer<Sticker> = StickerSerializer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object StickerSerializer : KSerializer<Sticker> {
|
||||||
|
override val descriptor: SerialDescriptor = StickerSurrogate.serializer().descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): Sticker {
|
||||||
|
val surrogate = StickerSurrogate.serializer().deserialize(decoder)
|
||||||
|
|
||||||
|
return when {
|
||||||
|
surrogate.is_animated == true -> AnimatedSticker(
|
||||||
|
surrogate.file_id,
|
||||||
|
surrogate.file_unique_id,
|
||||||
|
surrogate.width,
|
||||||
|
surrogate.height,
|
||||||
|
surrogate.thumb,
|
||||||
|
surrogate.emoji,
|
||||||
|
surrogate.set_name,
|
||||||
|
surrogate.mask_position,
|
||||||
|
surrogate.file_size
|
||||||
|
)
|
||||||
|
surrogate.is_video == true -> VideoSticker(
|
||||||
|
surrogate.file_id,
|
||||||
|
surrogate.file_unique_id,
|
||||||
|
surrogate.width,
|
||||||
|
surrogate.height,
|
||||||
|
surrogate.thumb,
|
||||||
|
surrogate.emoji,
|
||||||
|
surrogate.set_name,
|
||||||
|
surrogate.mask_position,
|
||||||
|
surrogate.file_size
|
||||||
|
)
|
||||||
|
else -> SimpleSticker(
|
||||||
|
surrogate.file_id,
|
||||||
|
surrogate.file_unique_id,
|
||||||
|
surrogate.width,
|
||||||
|
surrogate.height,
|
||||||
|
surrogate.thumb,
|
||||||
|
surrogate.emoji,
|
||||||
|
surrogate.set_name,
|
||||||
|
surrogate.mask_position,
|
||||||
|
surrogate.file_size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: Sticker) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SimpleSticker(
|
||||||
|
@SerialName(fileIdField)
|
||||||
|
override val fileId: FileId,
|
||||||
|
@SerialName(fileUniqueIdField)
|
||||||
|
override val fileUniqueId: FileUniqueId,
|
||||||
|
@SerialName(widthField)
|
||||||
|
override val width: Int,
|
||||||
|
@SerialName(heightField)
|
||||||
|
override val height: Int,
|
||||||
|
@SerialName(thumbField)
|
||||||
|
override val thumb: PhotoSize? = null,
|
||||||
|
@SerialName(emojiField)
|
||||||
|
override val emoji: String? = null,
|
||||||
|
@SerialName(stickerSetNameField)
|
||||||
|
override val stickerSetName: StickerSetName? = null,
|
||||||
|
@SerialName(maskPositionField)
|
||||||
|
override val maskPosition: MaskPosition? = null,
|
||||||
|
@SerialName(fileSizeField)
|
||||||
|
override val fileSize: Long? = null,
|
||||||
|
) : Sticker
|
||||||
|
@Serializable
|
||||||
|
data class AnimatedSticker(
|
||||||
|
@SerialName(fileIdField)
|
||||||
|
override val fileId: FileId,
|
||||||
|
@SerialName(fileUniqueIdField)
|
||||||
|
override val fileUniqueId: FileUniqueId,
|
||||||
|
@SerialName(widthField)
|
||||||
|
override val width: Int,
|
||||||
|
@SerialName(heightField)
|
||||||
|
override val height: Int,
|
||||||
|
@SerialName(thumbField)
|
||||||
|
override val thumb: PhotoSize? = null,
|
||||||
|
@SerialName(emojiField)
|
||||||
|
override val emoji: String? = null,
|
||||||
|
@SerialName(stickerSetNameField)
|
||||||
|
override val stickerSetName: StickerSetName? = null,
|
||||||
|
@SerialName(maskPositionField)
|
||||||
|
override val maskPosition: MaskPosition? = null,
|
||||||
|
@SerialName(fileSizeField)
|
||||||
|
override val fileSize: Long? = null,
|
||||||
|
) : Sticker
|
||||||
|
@Serializable
|
||||||
|
data class VideoSticker(
|
||||||
|
@SerialName(fileIdField)
|
||||||
|
override val fileId: FileId,
|
||||||
|
@SerialName(fileUniqueIdField)
|
||||||
|
override val fileUniqueId: FileUniqueId,
|
||||||
|
@SerialName(widthField)
|
||||||
|
override val width: Int,
|
||||||
|
@SerialName(heightField)
|
||||||
|
override val height: Int,
|
||||||
|
@SerialName(thumbField)
|
||||||
|
override val thumb: PhotoSize? = null,
|
||||||
|
@SerialName(emojiField)
|
||||||
|
override val emoji: String? = null,
|
||||||
|
@SerialName(stickerSetNameField)
|
||||||
|
override val stickerSetName: StickerSetName? = null,
|
||||||
|
@SerialName(maskPositionField)
|
||||||
|
override val maskPosition: MaskPosition? = null,
|
||||||
|
@SerialName(fileSizeField)
|
||||||
|
override val fileSize: Long? = null,
|
||||||
|
) : Sticker
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.FileUniqueId
|
||||||
|
|
||||||
internal const val fileIdField = "file_id"
|
|
||||||
internal const val fileSizeField = "file_size"
|
|
||||||
internal const val fileDateField = "file_date"
|
|
||||||
internal const val filePathField = "file_path"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare common part of media files in Telegram. Note: it is not representation of JVM `File` type
|
* Declare common part of media files in Telegram. Note: it is not representation of JVM `File` type
|
||||||
*/
|
*/
|
||||||
interface TelegramMediaFile {
|
sealed interface TelegramMediaFile {
|
||||||
val fileId: FileId
|
val fileId: FileId
|
||||||
val fileUniqueId: FileUniqueId
|
val fileUniqueId: FileUniqueId
|
||||||
val fileSize: Long?
|
val fileSize: Long?
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.files.PhotoSize
|
||||||
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
|
sealed interface ThumbedMediaFile : TelegramMediaFile {
|
||||||
|
val thumb: PhotoSize?
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
sealed interface TitledMediaFile {
|
||||||
|
val title: String?
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.files
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
|
||||||
|
|
||||||
internal const val fileNameField = "file_name"
|
|
||||||
|
|
||||||
interface CustomNamedMediaFile {
|
|
||||||
val fileName: String?
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.MimeTyped
|
|
||||||
|
|
||||||
internal const val mimeTypeField = "mime_type"
|
|
||||||
|
|
||||||
interface MimedMediaFile : TelegramMediaFile, MimeTyped
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.files.abstracts
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("CustomNamedMediaFile", "dev.inmo.tgbotapi.types.files.CustomNamedMediaFile"))
|
||||||
|
typealias CustomNamedMediaFile = dev.inmo.tgbotapi.types.files.CustomNamedMediaFile
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("MimedMediaFile", "dev.inmo.tgbotapi.types.files.MimedMediaFile"))
|
||||||
|
typealias MimedMediaFile = dev.inmo.tgbotapi.types.files.MimedMediaFile
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("PlayableMediaFile", "dev.inmo.tgbotapi.types.files.PlayableMediaFile"))
|
||||||
|
typealias PlayableMediaFile = dev.inmo.tgbotapi.types.files.PlayableMediaFile
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("SizedMediaFile", "dev.inmo.tgbotapi.types.files.SizedMediaFile"))
|
||||||
|
typealias SizedMediaFile = dev.inmo.tgbotapi.types.files.SizedMediaFile
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("TelegramMediaFile", "dev.inmo.tgbotapi.types.files.TelegramMediaFile"))
|
||||||
|
typealias TelegramMediaFile = dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("ThumbedMediaFile", "dev.inmo.tgbotapi.types.files.ThumbedMediaFile"))
|
||||||
|
typealias ThumbedMediaFile = dev.inmo.tgbotapi.types.files.ThumbedMediaFile
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("TitledMediaFile", "dev.inmo.tgbotapi.types.files.TitledMediaFile"))
|
||||||
|
typealias TitledMediaFile = dev.inmo.tgbotapi.types.files.TitledMediaFile
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
|
||||||
|
|
||||||
interface PlayableMediaFile : TelegramMediaFile {
|
|
||||||
val duration: Long?
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
|
||||||
|
|
||||||
interface SizedMediaFile : TelegramMediaFile {
|
|
||||||
val width: Int
|
|
||||||
val height: Int
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.files.PhotoSize
|
|
||||||
|
|
||||||
interface ThumbedMediaFile : TelegramMediaFile {
|
|
||||||
val thumb: PhotoSize?
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.abstracts
|
|
||||||
|
|
||||||
interface TitledMediaFile {
|
|
||||||
val title: String?
|
|
||||||
}
|
|
||||||
@@ -1,158 +1,19 @@
|
|||||||
package dev.inmo.tgbotapi.types.files.sticker
|
package dev.inmo.tgbotapi.types.files.sticker
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
@Deprecated("Replaced", ReplaceWith("StickerSurrogate", "dev.inmo.tgbotapi.types.files.StickerSurrogate"))
|
||||||
import dev.inmo.tgbotapi.types.*
|
typealias StickerSurrogate = dev.inmo.tgbotapi.types.files.StickerSurrogate
|
||||||
import dev.inmo.tgbotapi.types.files.PhotoSize
|
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
|
||||||
import kotlinx.serialization.encoding.Decoder
|
|
||||||
import kotlinx.serialization.encoding.Encoder
|
|
||||||
|
|
||||||
@Serializable
|
@Deprecated("Replaced", ReplaceWith("Sticker", "dev.inmo.tgbotapi.types.files.Sticker"))
|
||||||
@RiskFeature("This class is used for serialization/deserialization of Sticker interface")
|
typealias Sticker = dev.inmo.tgbotapi.types.files.Sticker
|
||||||
data class StickerSurrogate(
|
|
||||||
val file_id: FileId,
|
|
||||||
val file_unique_id: FileUniqueId,
|
|
||||||
val width: Int,
|
|
||||||
val height: Int,
|
|
||||||
val is_animated: Boolean? = null,
|
|
||||||
val is_video: Boolean? = null,
|
|
||||||
val thumb: PhotoSize? = null,
|
|
||||||
val emoji: String? = null,
|
|
||||||
val set_name: StickerSetName? = null,
|
|
||||||
val mask_position: MaskPosition? = null,
|
|
||||||
val file_size: Long? = null
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO:: Serializer
|
@Deprecated("Replaced", ReplaceWith("StickerSerializer", "dev.inmo.tgbotapi.types.files.StickerSerializer"))
|
||||||
@Serializable(StickerSerializer::class)
|
typealias StickerSerializer = dev.inmo.tgbotapi.types.files.StickerSerializer
|
||||||
sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile {
|
|
||||||
val emoji: String?
|
|
||||||
val maskPosition: MaskPosition?
|
|
||||||
val stickerSetName: StickerSetName?
|
|
||||||
|
|
||||||
val isAnimated
|
@Deprecated("Replaced", ReplaceWith("SimpleSticker", "dev.inmo.tgbotapi.types.files.SimpleSticker"))
|
||||||
get() = this is AnimatedSticker
|
typealias SimpleSticker = dev.inmo.tgbotapi.types.files.SimpleSticker
|
||||||
val isVideo
|
|
||||||
get() = this is VideoSticker
|
|
||||||
|
|
||||||
companion object {
|
@Deprecated("Replaced", ReplaceWith("AnimatedSticker", "dev.inmo.tgbotapi.types.files.AnimatedSticker"))
|
||||||
fun serializer(): KSerializer<Sticker> = StickerSerializer
|
typealias AnimatedSticker = dev.inmo.tgbotapi.types.files.AnimatedSticker
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object StickerSerializer : KSerializer<Sticker> {
|
@Deprecated("Replaced", ReplaceWith("VideoSticker", "dev.inmo.tgbotapi.types.files.VideoSticker"))
|
||||||
override val descriptor: SerialDescriptor = StickerSurrogate.serializer().descriptor
|
typealias VideoSticker = dev.inmo.tgbotapi.types.files.VideoSticker
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): Sticker {
|
|
||||||
val surrogate = StickerSurrogate.serializer().deserialize(decoder)
|
|
||||||
|
|
||||||
return when {
|
|
||||||
surrogate.is_animated == true -> AnimatedSticker(
|
|
||||||
surrogate.file_id,
|
|
||||||
surrogate.file_unique_id,
|
|
||||||
surrogate.width,
|
|
||||||
surrogate.height,
|
|
||||||
surrogate.thumb,
|
|
||||||
surrogate.emoji,
|
|
||||||
surrogate.set_name,
|
|
||||||
surrogate.mask_position,
|
|
||||||
surrogate.file_size
|
|
||||||
)
|
|
||||||
surrogate.is_video == true -> VideoSticker(
|
|
||||||
surrogate.file_id,
|
|
||||||
surrogate.file_unique_id,
|
|
||||||
surrogate.width,
|
|
||||||
surrogate.height,
|
|
||||||
surrogate.thumb,
|
|
||||||
surrogate.emoji,
|
|
||||||
surrogate.set_name,
|
|
||||||
surrogate.mask_position,
|
|
||||||
surrogate.file_size
|
|
||||||
)
|
|
||||||
else -> SimpleSticker(
|
|
||||||
surrogate.file_id,
|
|
||||||
surrogate.file_unique_id,
|
|
||||||
surrogate.width,
|
|
||||||
surrogate.height,
|
|
||||||
surrogate.thumb,
|
|
||||||
surrogate.emoji,
|
|
||||||
surrogate.set_name,
|
|
||||||
surrogate.mask_position,
|
|
||||||
surrogate.file_size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, value: Sticker) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SimpleSticker(
|
|
||||||
@SerialName(fileIdField)
|
|
||||||
override val fileId: FileId,
|
|
||||||
@SerialName(fileUniqueIdField)
|
|
||||||
override val fileUniqueId: FileUniqueId,
|
|
||||||
@SerialName(widthField)
|
|
||||||
override val width: Int,
|
|
||||||
@SerialName(heightField)
|
|
||||||
override val height: Int,
|
|
||||||
@SerialName(thumbField)
|
|
||||||
override val thumb: PhotoSize? = null,
|
|
||||||
@SerialName(emojiField)
|
|
||||||
override val emoji: String? = null,
|
|
||||||
@SerialName(stickerSetNameField)
|
|
||||||
override val stickerSetName: StickerSetName? = null,
|
|
||||||
@SerialName(maskPositionField)
|
|
||||||
override val maskPosition: MaskPosition? = null,
|
|
||||||
@SerialName(fileSizeField)
|
|
||||||
override val fileSize: Long? = null,
|
|
||||||
) : Sticker
|
|
||||||
@Serializable
|
|
||||||
data class AnimatedSticker(
|
|
||||||
@SerialName(fileIdField)
|
|
||||||
override val fileId: FileId,
|
|
||||||
@SerialName(fileUniqueIdField)
|
|
||||||
override val fileUniqueId: FileUniqueId,
|
|
||||||
@SerialName(widthField)
|
|
||||||
override val width: Int,
|
|
||||||
@SerialName(heightField)
|
|
||||||
override val height: Int,
|
|
||||||
@SerialName(thumbField)
|
|
||||||
override val thumb: PhotoSize? = null,
|
|
||||||
@SerialName(emojiField)
|
|
||||||
override val emoji: String? = null,
|
|
||||||
@SerialName(stickerSetNameField)
|
|
||||||
override val stickerSetName: StickerSetName? = null,
|
|
||||||
@SerialName(maskPositionField)
|
|
||||||
override val maskPosition: MaskPosition? = null,
|
|
||||||
@SerialName(fileSizeField)
|
|
||||||
override val fileSize: Long? = null,
|
|
||||||
) : Sticker
|
|
||||||
@Serializable
|
|
||||||
data class VideoSticker(
|
|
||||||
@SerialName(fileIdField)
|
|
||||||
override val fileId: FileId,
|
|
||||||
@SerialName(fileUniqueIdField)
|
|
||||||
override val fileUniqueId: FileUniqueId,
|
|
||||||
@SerialName(widthField)
|
|
||||||
override val width: Int,
|
|
||||||
@SerialName(heightField)
|
|
||||||
override val height: Int,
|
|
||||||
@SerialName(thumbField)
|
|
||||||
override val thumb: PhotoSize? = null,
|
|
||||||
@SerialName(emojiField)
|
|
||||||
override val emoji: String? = null,
|
|
||||||
@SerialName(stickerSetNameField)
|
|
||||||
override val stickerSetName: StickerSetName? = null,
|
|
||||||
@SerialName(maskPositionField)
|
|
||||||
override val maskPosition: MaskPosition? = null,
|
|
||||||
@SerialName(fileSizeField)
|
|
||||||
override val fileSize: Long? = null,
|
|
||||||
) : Sticker
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
|||||||
import dev.inmo.tgbotapi.types.chat.abstracts.*
|
import dev.inmo.tgbotapi.types.chat.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.dice.Dice
|
import dev.inmo.tgbotapi.types.dice.Dice
|
||||||
import dev.inmo.tgbotapi.types.files.*
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
import dev.inmo.tgbotapi.types.games.RawGame
|
import dev.inmo.tgbotapi.types.games.RawGame
|
||||||
import dev.inmo.tgbotapi.types.location.Location
|
import dev.inmo.tgbotapi.types.location.Location
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.abstracts
|
package dev.inmo.tgbotapi.types.message.content.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
interface MediaCollectionContent<T: TelegramMediaFile>: MessageContent, MediaContent {
|
interface MediaCollectionContent<T: TelegramMediaFile>: MessageContent, MediaContent {
|
||||||
val mediaCollection: List<T>
|
val mediaCollection: List<T>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.abstracts
|
package dev.inmo.tgbotapi.types.message.content.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMedia
|
import dev.inmo.tgbotapi.types.InputMedia.InputMedia
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
|
||||||
interface MediaContent: MessageContent {
|
interface MediaContent: MessageContent {
|
||||||
val media: TelegramMediaFile
|
val media: TelegramMediaFile
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ interface MessageContent: ResendableContent {
|
|||||||
subclass(DiceContent::class)
|
subclass(DiceContent::class)
|
||||||
subclass(TextContent::class)
|
subclass(TextContent::class)
|
||||||
|
|
||||||
subclass(LocationContent::class, LocationContentSerializer)
|
subclass(LiveLocationContent::class)
|
||||||
|
subclass(StaticLocationContent::class)
|
||||||
|
|
||||||
subclass(PhotoContent::class)
|
subclass(PhotoContent::class)
|
||||||
subclass(VideoContent::class)
|
subclass(VideoContent::class)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.types.ChatIdentifier
|
|||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.passport.encrypted
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
|
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.*
|
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.passport.encrypted
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
|
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
|
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.*
|
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.passport.encrypted
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
|
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
|
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.*
|
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
|||||||
@@ -1,23 +1,4 @@
|
|||||||
package dev.inmo.tgbotapi.types.passport.encrypted
|
package dev.inmo.tgbotapi.types.passport.encrypted
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
@Deprecated("Replaced", ReplaceWith("PassportFile", "dev.inmo.tgbotapi.types.files.PassportFile"))
|
||||||
import dev.inmo.tgbotapi.types.*
|
typealias PassportFile = dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
|
||||||
import kotlinx.serialization.SerialName
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This object represents a file uploaded to Telegram Passport. Currently all Telegram Passport files are in JPEG format
|
|
||||||
* when decrypted and don't exceed 10MB.
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
data class PassportFile(
|
|
||||||
@SerialName(fileIdField)
|
|
||||||
override val fileId: FileId,
|
|
||||||
@SerialName(fileUniqueIdField)
|
|
||||||
override val fileUniqueId: FileUniqueId,
|
|
||||||
@SerialName(fileDateField)
|
|
||||||
val uploadingDate: TelegramDate,
|
|
||||||
@SerialName(fileSizeField)
|
|
||||||
override val fileSize: Long? = null
|
|
||||||
) : TelegramMediaFile
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(EncryptedElementSerializer::class)
|
@Serializable(EncryptedElementSerializer::class)
|
||||||
interface EncryptedPassportElementTranslatable : EncryptedPassportElement {
|
interface EncryptedPassportElementTranslatable : EncryptedPassportElement {
|
||||||
val translations: List<PassportFile>
|
val translations: List<PassportFile>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(EncryptedElementSerializer::class)
|
@Serializable(EncryptedElementSerializer::class)
|
||||||
interface EncryptedPassportElementWithFilesCollection : EncryptedPassportElement {
|
interface EncryptedPassportElementWithFilesCollection : EncryptedPassportElement {
|
||||||
val files: List<PassportFile>
|
val files: List<PassportFile>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(EncryptedElementSerializer::class)
|
@Serializable(EncryptedElementSerializer::class)
|
||||||
interface EncryptedPassportElementWithFrontSide : EncryptedPassportElement {
|
interface EncryptedPassportElementWithFrontSide : EncryptedPassportElement {
|
||||||
val frontSide: PassportFile?
|
val frontSide: PassportFile?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(EncryptedElementSerializer::class)
|
@Serializable(EncryptedElementSerializer::class)
|
||||||
interface EncryptedPassportElementWithReverseSide : EncryptedPassportElement {
|
interface EncryptedPassportElementWithReverseSide : EncryptedPassportElement {
|
||||||
val reverseSide: PassportFile?
|
val reverseSide: PassportFile?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
package dev.inmo.tgbotapi.types.passport.encrypted.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile
|
import dev.inmo.tgbotapi.types.files.PassportFile
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(EncryptedElementSerializer::class)
|
@Serializable(EncryptedElementSerializer::class)
|
||||||
interface EncryptedPassportElementWithSelfie : EncryptedPassportElement {
|
interface EncryptedPassportElementWithSelfie : EncryptedPassportElement {
|
||||||
val selfie: PassportFile?
|
val selfie: PassportFile?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.stickers
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.files.PhotoSize
|
import dev.inmo.tgbotapi.types.files.PhotoSize
|
||||||
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
import dev.inmo.tgbotapi.types.files.Sticker
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.utils
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.crypto.SourceBytes
|
|
||||||
import dev.inmo.micro_utils.crypto.SourceString
|
|
||||||
|
|
||||||
internal expect fun SourceString.hmacSha256(key: String): String
|
|
||||||
private val HEX_ARRAY = "0123456789abcdef".toCharArray()
|
|
||||||
|
|
||||||
internal fun SourceBytes.hex(): String {
|
|
||||||
val hexChars = CharArray(size * 2)
|
|
||||||
for (j in indices) {
|
|
||||||
val v: Int = this[j].toInt() and 0xFF
|
|
||||||
hexChars[j * 2] = HEX_ARRAY[v ushr 4]
|
|
||||||
hexChars[j * 2 + 1] = HEX_ARRAY[v and 0x0F]
|
|
||||||
}
|
|
||||||
return hexChars.concatToString()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun SourceString.hex(): String = encodeToByteArray().hex()
|
|
||||||
@@ -16,33 +16,16 @@ private inline val String.withoutLastSlash: String
|
|||||||
|
|
||||||
class TelegramAPIUrlsKeeper(
|
class TelegramAPIUrlsKeeper(
|
||||||
token: String,
|
token: String,
|
||||||
hostUrl: String = telegramBotAPIDefaultUrl,
|
hostUrl: String = telegramBotAPIDefaultUrl
|
||||||
urlsSuffixes: String = ""
|
|
||||||
) {
|
) {
|
||||||
val webAppDataSecretKey by lazy {
|
|
||||||
token.hmacSha256("WebAppData")
|
|
||||||
}
|
|
||||||
|
|
||||||
val commonAPIUrl: String
|
val commonAPIUrl: String
|
||||||
val fileBaseUrl: String
|
val fileBaseUrl: String
|
||||||
|
|
||||||
constructor(token: String, testServer: Boolean, hostUrl: String = telegramBotAPIDefaultUrl) : this(
|
|
||||||
token,
|
|
||||||
hostUrl,
|
|
||||||
"/test".takeIf { testServer } ?: ""
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val correctedHost = hostUrl.withoutLastSlash
|
val correctedHost = hostUrl.withoutLastSlash
|
||||||
commonAPIUrl = "$correctedHost/bot$token$urlsSuffixes"
|
commonAPIUrl = "$correctedHost/bot$token"
|
||||||
fileBaseUrl = "$correctedHost/file/bot$token$urlsSuffixes"
|
fileBaseUrl = "$correctedHost/file/bot$token"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
||||||
|
|
||||||
/**
|
|
||||||
* @param rawData Data from [dev.inmo.tgbotapi.webapps.WebApp.initData]
|
|
||||||
* @param hash Data from [dev.inmo.tgbotapi.webapps.WebApp.initDataUnsafe] from the field [dev.inmo.tgbotapi.webapps.WebAppInitData.hash]
|
|
||||||
*/
|
|
||||||
fun checkWebAppLink(rawData: String, hash: String) = rawData.hmacSha256(webAppDataSecretKey).hex() == hash
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.utils
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.crypto.CryptoJS
|
|
||||||
import dev.inmo.micro_utils.crypto.SourceString
|
|
||||||
|
|
||||||
actual fun SourceString.hmacSha256(key: String) = CryptoJS.asDynamic().HmacSHA256(this, key).toString().unsafeCast<String>()
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.utils
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.crypto.SourceString
|
|
||||||
import javax.crypto.Mac
|
|
||||||
import javax.crypto.spec.SecretKeySpec
|
|
||||||
|
|
||||||
actual fun SourceString.hmacSha256(key: String): String {
|
|
||||||
val mac = Mac.getInstance("HmacSHA256")
|
|
||||||
|
|
||||||
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA256")
|
|
||||||
mac.init(secretKey)
|
|
||||||
|
|
||||||
return mac.doFinal(toByteArray()).hex()
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user