mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-24 16:26:01 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61be689aca | |||
| 03f8d65bb6 | |||
| 2dc8beba8a | |||
| 5451adf4ac | |||
| 9982534001 | |||
| c0451d4c8f | |||
| a9d65944e6 | |||
| 39598dcb69 | |||
| 3069a6084c | |||
| e7bbce3fa7 | |||
| 0b361163f2 | |||
| 6aba2ff641 | |||
| 6b761ab37d | |||
| b9c8a89af9 | |||
| a42c5c63c4 | |||
| fc1a029acb | |||
| f90ae2f918 | |||
| 019b260888 | |||
| 0831f2fa75 | |||
| 32ae9d2b16 | |||
| b975a1b036 | |||
| f4b1e4a150 | |||
| 97031512d4 |
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,5 +1,32 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 0.33.4
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `uuid`: `0.2.3` -> `0.2.4`
|
||||
* `MicroUtils`: `0.4.33` -> `0.4.35`
|
||||
* `Core`:
|
||||
* All `TextSource` implementators have become `Serializable`
|
||||
* New serializer `TextSourceSerializer`
|
||||
* Interface`FromUserMessage` now extends `Message`
|
||||
* New interface `FromUser`
|
||||
* Interface `FromUserMessage` now extends `FromUser`
|
||||
* `Extensions Utils`
|
||||
* Fixes in `parseCommandsWithParams`
|
||||
|
||||
## 0.33.3
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.4.32` -> `0.4.33`
|
||||
* `Ktor`: `1.5.2` -> `1.5.3`
|
||||
* `API`:
|
||||
* Bot actions DSL (fix for [#358](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/358))
|
||||
* `Behaviour Builder`:
|
||||
* Rewrite logic of `doInSubContextWithUpdatesFilter` and `doInSubContextWithFlowsUpdatesFilterSetup` extensions
|
||||
* All triggers now work with `stopOnCompletion` set up to `false`
|
||||
|
||||
## 0.33.2
|
||||
|
||||
* `Common`:
|
||||
|
||||
11
build.gradle
11
build.gradle
@@ -18,6 +18,17 @@ plugins {
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" apply false
|
||||
}
|
||||
|
||||
// temporal crutch until legacy tests will be stabled or legacy target will be removed
|
||||
allprojects {
|
||||
if (it != rootProject.findProject("docs")) {
|
||||
tasks.whenTaskAdded { task ->
|
||||
if(task.name == "jsLegacyBrowserTest" || task.name == "jsLegacyNodeTest") {
|
||||
task.enabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getCurrentVersionChangelog() {
|
||||
OutputStream changelogDataOS = new ByteArrayOutputStream()
|
||||
exec {
|
||||
|
||||
@@ -9,14 +9,14 @@ kotlin_version=1.4.32
|
||||
kotlin_coroutines_version=1.4.3
|
||||
kotlin_serialisation_runtime_version=1.1.0
|
||||
klock_version=2.0.7
|
||||
uuid_version=0.2.3
|
||||
ktor_version=1.5.2
|
||||
uuid_version=0.2.4
|
||||
ktor_version=1.5.3
|
||||
|
||||
micro_utils_version=0.4.32
|
||||
micro_utils_version=0.4.35
|
||||
|
||||
javax_activation_version=1.1.1
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=0.33.2
|
||||
library_version=0.33.4
|
||||
|
||||
github_release_plugin_version=2.2.12
|
||||
|
||||
@@ -52,6 +52,7 @@ kotlin {
|
||||
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
|
||||
api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version"
|
||||
api "dev.inmo:micro_utils.serialization.encapsulator:$micro_utils_version"
|
||||
api "dev.inmo:micro_utils.serialization.typed_serializer:$micro_utils_version"
|
||||
|
||||
api "io.ktor:ktor-client-core:$ktor_version"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.CommonAbstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
|
||||
interface FromUser {
|
||||
val user: User
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
package dev.inmo.tgbotapi.CommonAbstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourceSerializer
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.regular
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.toTextParts
|
||||
import dev.inmo.tgbotapi.types.captionLength
|
||||
import dev.inmo.tgbotapi.types.textLength
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
const val DirectInvocationOfTextSourceConstructor = "It is strongly not recommended to use constructors directly instead of factory methods"
|
||||
|
||||
typealias TextSourcesList = List<TextSource>
|
||||
|
||||
@Serializable(TextSourceSerializer::class)
|
||||
interface TextSource {
|
||||
val markdown: String
|
||||
val markdownV2: String
|
||||
@@ -17,6 +20,10 @@ interface TextSource {
|
||||
|
||||
val asText: String
|
||||
get() = source
|
||||
|
||||
companion object {
|
||||
fun serializer() = TextSourceSerializer
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
@@ -28,8 +35,13 @@ inline operator fun TextSource.plus(text: String) = listOf(this, regular(text))
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline operator fun List<TextSource>.plus(text: String) = this + regular(text)
|
||||
|
||||
@Serializable(TextSourceSerializer::class)
|
||||
interface MultilevelTextSource : TextSource {
|
||||
val subsources: List<TextSource>
|
||||
|
||||
companion object {
|
||||
fun serializer() = TextSourceSerializer
|
||||
}
|
||||
}
|
||||
|
||||
data class TextPart(
|
||||
|
||||
@@ -80,6 +80,8 @@ val openPeriodPollSecondsLimit = 5 .. 600
|
||||
|
||||
val membersLimit = 1 .. 99999
|
||||
|
||||
const val botActionActualityTime: Seconds = 5
|
||||
|
||||
// Made as lazy for correct work in K/JS
|
||||
val telegramInlineModeGifPermittedMimeTypes by lazy {
|
||||
listOf(
|
||||
|
||||
@@ -3,10 +3,13 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see bold
|
||||
*/
|
||||
@Serializable
|
||||
data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -4,12 +4,14 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
private val commandRegex = Regex("[/!][^@\\s]*")
|
||||
|
||||
/**
|
||||
* @see botCommand
|
||||
*/
|
||||
@Serializable
|
||||
data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see cashTag
|
||||
*/
|
||||
@Serializable
|
||||
data class CashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see code
|
||||
*/
|
||||
@Serializable
|
||||
data class CodeTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see email
|
||||
*/
|
||||
@Serializable
|
||||
data class EMailTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see hashtag
|
||||
*/
|
||||
@Serializable
|
||||
data class HashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see italic
|
||||
*/
|
||||
@Serializable
|
||||
data class ItalicTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
private val String.withoutCommercialAt
|
||||
get() = if (startsWith("@")) {
|
||||
@@ -14,6 +15,7 @@ private val String.withoutCommercialAt
|
||||
/**
|
||||
* @see mention
|
||||
*/
|
||||
@Serializable
|
||||
data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see phone
|
||||
*/
|
||||
@Serializable
|
||||
data class PhoneNumberTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see pre
|
||||
*/
|
||||
@Serializable
|
||||
data class PreTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
val language: String? = null
|
||||
|
||||
@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see regular
|
||||
*/
|
||||
@Serializable
|
||||
data class RegularTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see strikethrough
|
||||
*/
|
||||
@Serializable
|
||||
data class StrikethroughTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see link
|
||||
*/
|
||||
@Serializable
|
||||
data class TextLinkTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
val url: String
|
||||
|
||||
@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see mention
|
||||
*/
|
||||
@Serializable
|
||||
data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
val user: User,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.micro_utils.serialization.typed_serializer.TypedSerializer
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.justTextSources
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.encoding.*
|
||||
|
||||
private val baseSerializers: Map<String, KSerializer<out TextSource>> = mapOf(
|
||||
"regular" to RegularTextSource.serializer(),
|
||||
"text_link" to TextLinkTextSource.serializer(),
|
||||
"code" to CodeTextSource.serializer(),
|
||||
"url" to URLTextSource.serializer(),
|
||||
"pre" to PreTextSource.serializer(),
|
||||
"bot_command" to BotCommandTextSource.serializer(),
|
||||
"strikethrough" to StrikethroughTextSource.serializer(),
|
||||
"italic" to ItalicTextSource.serializer(),
|
||||
"bold" to BoldTextSource.serializer(),
|
||||
"email" to EMailTextSource.serializer(),
|
||||
"underline" to UnderlineTextSource.serializer(),
|
||||
"mention" to MentionTextSource.serializer(),
|
||||
"phone_number" to PhoneNumberTextSource.serializer(),
|
||||
"text_mention" to TextMentionTextSource.serializer(),
|
||||
"hashtag" to HashTagTextSource.serializer(),
|
||||
"cashtag" to CashTagTextSource.serializer(),
|
||||
)
|
||||
|
||||
object TextSourceSerializer : TypedSerializer<TextSource>(TextSource::class, baseSerializers) {
|
||||
override fun <T: TextSource> include(type: String, serializer: KSerializer<T>) {
|
||||
require(type !in baseSerializers.keys)
|
||||
super.include(type, serializer)
|
||||
}
|
||||
|
||||
override fun exclude(type: String) {
|
||||
require(type !in baseSerializers.keys)
|
||||
super.exclude(type)
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see link
|
||||
*/
|
||||
@Serializable
|
||||
data class URLTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
|
||||
@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see underline
|
||||
*/
|
||||
@Serializable
|
||||
data class UnderlineTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: List<TextSource>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.FromUser
|
||||
|
||||
interface FromUserMessage {
|
||||
val user: User
|
||||
}
|
||||
interface FromUserMessage : FromUser, Message
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package dev.inmo.tgbotapi.types
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.makeString
|
||||
import dev.inmo.tgbotapi.TestsJsonFormat
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.*
|
||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourceSerializer
|
||||
import kotlinx.serialization.PolymorphicSerializer
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class TextSourcesTests {
|
||||
@Test
|
||||
fun testThatTextSourcesSerializedCorrectly() {
|
||||
val testList = buildEntities {
|
||||
bold(
|
||||
buildEntities {
|
||||
italic("It")
|
||||
regular(" ")
|
||||
link("is example", "https://is.example")
|
||||
}
|
||||
)
|
||||
regular(" ")
|
||||
underline("of")
|
||||
regular(" ")
|
||||
strikethrough("complex")
|
||||
regular(" ")
|
||||
pre("text", "kotlin")
|
||||
}
|
||||
val serialized = TestsJsonFormat.encodeToString(ListSerializer(TextSource.serializer()), testList)
|
||||
val deserialized = TestsJsonFormat.decodeFromString(
|
||||
ListSerializer(TextSource.serializer()),
|
||||
serialized
|
||||
)
|
||||
assertEquals(testList, deserialized)
|
||||
assertEquals(testList.makeString(), deserialized.makeString())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.send
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.send.SendAction
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.actions.*
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
private const val refreshTime: MilliSeconds = (botActionActualityTime - 1) * 1000L
|
||||
typealias TelegramBotActionCallback<T> = suspend TelegramBot.() -> T
|
||||
|
||||
suspend fun <T> TelegramBot.withAction(
|
||||
actionRequest: SendAction,
|
||||
block: TelegramBotActionCallback<T>
|
||||
): T {
|
||||
val botActionJob = supervisorScope {
|
||||
launch {
|
||||
while (isActive) {
|
||||
delay(refreshTime)
|
||||
safelyWithoutExceptions {
|
||||
execute(actionRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return try {
|
||||
safely { block() }
|
||||
} finally {
|
||||
botActionJob.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <T> TelegramBot.withAction(
|
||||
chatId: ChatId,
|
||||
action: BotAction,
|
||||
block: TelegramBotActionCallback<T>
|
||||
) = withAction(
|
||||
SendAction(chatId, action),
|
||||
block
|
||||
)
|
||||
|
||||
suspend fun <T> TelegramBot.withAction(
|
||||
chat: Chat,
|
||||
action: BotAction,
|
||||
block: TelegramBotActionCallback<T>
|
||||
) = withAction(
|
||||
chat.id,
|
||||
action,
|
||||
block
|
||||
)
|
||||
|
||||
suspend fun <T> TelegramBot.withTypingAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, TypingAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadPhotoAction, block)
|
||||
suspend fun <T> TelegramBot.withRecordVideoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, RecordVideoAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadVideoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadVideoAction, block)
|
||||
suspend fun <T> TelegramBot.withRecordAudioAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, RecordAudioAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadAudioAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadAudioAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadDocumentAction, block)
|
||||
suspend fun <T> TelegramBot.withFindLocationAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, FindLocationAction, block)
|
||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, RecordVideoNoteAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadVideoNoteAction, block)
|
||||
|
||||
|
||||
suspend fun <T> TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, TypingAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadPhotoAction, block)
|
||||
suspend fun <T> TelegramBot.withRecordVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, RecordVideoAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadVideoAction, block)
|
||||
suspend fun <T> TelegramBot.withRecordAudioAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, RecordAudioAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadAudioAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadAudioAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadDocumentAction, block)
|
||||
suspend fun <T> TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, FindLocationAction, block)
|
||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, RecordVideoNoteAction, block)
|
||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadVideoNoteAction, block)
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.inmo.tgbotapi.extensions.behaviour_builder
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
import dev.inmo.micro_utils.coroutines.weakLaunch
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||
@@ -36,14 +37,15 @@ suspend fun <T> BehaviourContext.doInSubContextWithFlowsUpdatesFilterSetup(
|
||||
newFlowsUpdatesFilterSetUp: BehaviourContextAndTypeReceiver<Unit, FlowsUpdatesFilter>?,
|
||||
stopOnCompletion: Boolean = true,
|
||||
behaviourContextReceiver: BehaviourContextReceiver<T>
|
||||
) = copy(
|
||||
flowsUpdatesFilter = FlowsUpdatesFilter(),
|
||||
scope = CoroutineScope(scope.coroutineContext + SupervisorJob())
|
||||
).run {
|
||||
): T = supervisorScope {
|
||||
val newContext = copy(
|
||||
flowsUpdatesFilter = FlowsUpdatesFilter(),
|
||||
scope = this
|
||||
)
|
||||
newFlowsUpdatesFilterSetUp ?.let {
|
||||
it.apply { invoke(this@run, this@doInSubContextWithFlowsUpdatesFilterSetup.flowsUpdatesFilter) }
|
||||
it.apply { invoke(newContext, this@doInSubContextWithFlowsUpdatesFilterSetup.flowsUpdatesFilter) }
|
||||
}
|
||||
behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
||||
newContext.behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,13 +56,17 @@ suspend fun <T> BehaviourContext.doInSubContextWithUpdatesFilter(
|
||||
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?,
|
||||
stopOnCompletion: Boolean = true,
|
||||
behaviourContextReceiver: BehaviourContextReceiver<T>
|
||||
) = doInSubContextWithFlowsUpdatesFilterSetup(
|
||||
): T = doInSubContextWithFlowsUpdatesFilterSetup(
|
||||
newFlowsUpdatesFilterSetUp = updatesFilter ?.let {
|
||||
{ oldOne ->
|
||||
oldOne.allUpdatesFlow.filter { updatesFilter(it) }.subscribeSafelyWithoutExceptions(this, asUpdateReceiver)
|
||||
weakLaunch {
|
||||
oldOne.allUpdatesFlow.filter { updatesFilter(it) }.subscribeSafelyWithoutExceptions(this, asUpdateReceiver)
|
||||
}
|
||||
}
|
||||
} ?: { oldOne ->
|
||||
oldOne.allUpdatesFlow.subscribeSafelyWithoutExceptions(this, asUpdateReceiver)
|
||||
weakLaunch {
|
||||
oldOne.allUpdatesFlow.subscribeSafelyWithoutExceptions(this, asUpdateReceiver)
|
||||
}
|
||||
},
|
||||
stopOnCompletion,
|
||||
behaviourContextReceiver
|
||||
|
||||
@@ -26,7 +26,8 @@ internal suspend inline fun <reified T : CallbackQuery> BehaviourContext.onCallb
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerQuery.user.id.chatId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerQuery)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ internal suspend inline fun <reified U : ChatMemberUpdatedUpdate> BehaviourConte
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerChatMemberUpdated.chat.id.chatId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerChatMemberUpdated)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ internal suspend inline fun <reified T : MessageContent> BehaviourContext.onCont
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerMessage)
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||
} else null
|
||||
} else null,
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerMessage)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ internal suspend inline fun <reified T : InlineQuery> BehaviourContext.onInlineQ
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerQuery.from.id.chatId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerQuery)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.bui
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == mediaGroupChat.id.chatId }
|
||||
} else null
|
||||
} else null,
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(mediaGroup)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ suspend inline fun <reified T : EncryptedPassportElement> BehaviourContext.onPas
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||
} else null
|
||||
} else null,
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerMessage)
|
||||
}
|
||||
|
||||
@@ -513,6 +513,10 @@ inline fun Message.asPossiblySentViaBotCommonMessage(): PossiblySentViaBotCommon
|
||||
@PreviewFeature
|
||||
inline fun Message.requirePossiblySentViaBotCommonMessage(): PossiblySentViaBotCommonMessage<MessageContent> = this as PossiblySentViaBotCommonMessage<MessageContent>
|
||||
@PreviewFeature
|
||||
inline fun Message.asFromUserMessage(): FromUserMessage? = this as? FromUserMessage
|
||||
@PreviewFeature
|
||||
inline fun Message.requireFromUserMessage(): FromUserMessage = this as FromUserMessage
|
||||
@PreviewFeature
|
||||
inline fun BotAction.asFindLocationAction(): FindLocationAction? = this as? FindLocationAction
|
||||
@PreviewFeature
|
||||
inline fun BotAction.requireFindLocationAction(): FindLocationAction = this as FindLocationAction
|
||||
|
||||
@@ -18,8 +18,11 @@ fun List<TextSource>.parseCommandsWithParams(
|
||||
var currentBotCommandSource: BotCommandTextSource? = null
|
||||
var currentArgs = ""
|
||||
fun includeCurrent() = currentBotCommandSource ?.let {
|
||||
result[it.command] = currentArgs.split(argsSeparator).toTypedArray()
|
||||
currentArgs = ""
|
||||
currentArgs = currentArgs.trim()
|
||||
if (currentArgs.isNotEmpty()) {
|
||||
result[it.command] = currentArgs.split(argsSeparator).toTypedArray()
|
||||
currentArgs = ""
|
||||
}
|
||||
}
|
||||
for (textSource in this) {
|
||||
if (textSource is BotCommandTextSource) {
|
||||
|
||||
Reference in New Issue
Block a user