1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-19 13:55:57 +00:00

Compare commits

..

64 Commits

Author SHA1 Message Date
eaee334ff6 Update gradle-wrapper.properties 2021-05-08 16:44:14 +06:00
5c694e8625 Update CHANGELOG.md 2021-05-06 13:24:23 +06:00
0306c40fb2 Update CHANGELOG.md 2021-05-06 13:24:11 +06:00
fd915553e3 Merge pull request #381 from InsanusMokrassar/0.34.1
0.34.1
2021-05-05 19:37:32 +06:00
ec1c0ba8bb update microutils 2021-05-05 19:20:51 +06:00
12a64ec1d1 update ktor 2021-05-05 19:12:59 +06:00
59d7a7c781 fix in text sources list creating 2021-05-05 19:02:22 +06:00
cabfd7c76b start 0.34.1 2021-05-05 18:53:26 +06:00
f12f52899c Merge pull request #369 from InsanusMokrassar/renovate/org.jetbrains.dokka-gfm-plugin-1.x
Update dependency org.jetbrains.dokka:gfm-plugin to v1.4.32
2021-04-30 09:55:54 +06:00
Renovate Bot
ed067db20f Update dependency org.jetbrains.dokka:gfm-plugin to v1.4.32 2021-04-29 13:36:31 +00:00
b055268979 Merge pull request #362 from InsanusMokrassar/0.34.0
0.34.0
2021-04-29 19:03:29 +06:00
2584839d66 update core readme 2021-04-29 19:02:51 +06:00
63946e860d note about UnknownExtendedChat 2021-04-29 17:45:19 +06:00
90df436c63 small refactor of usage TextedInput 2021-04-29 17:40:01 +06:00
d3c8b49b10 Update CHANGELOG.md 2021-04-29 17:33:27 +06:00
c1372b55bc Note about ChatType in CHANGRLOG 2021-04-29 15:26:08 +06:00
b6c7ece995 small hotfix 2021-04-29 15:09:45 +06:00
44e7c80f43 remove redundant extensions for parseCommandsWithParams 2021-04-29 15:08:05 +06:00
1e41e95333 fixes in parseCommandsWithParams 2021-04-29 15:07:16 +06:00
03d4d715c0 hotfix 2021-04-29 11:59:44 +06:00
ab060d02ea deprecate Explained 2021-04-29 11:59:44 +06:00
f447be02dc Update InlineKeyboardMarkup.kt 2021-04-29 01:18:07 +06:00
eb923a6338 fixes 2021-04-28 23:22:13 +06:00
0914710cc7 update voice chats 2021-04-28 20:08:02 +06:00
1f7450844f optimize imports 2021-04-28 19:59:30 +06:00
167c214e35 migration to avoid using of TextPart 2021-04-28 19:54:57 +06:00
42a8d649cd Update CHANGELOG.md 2021-04-27 23:43:04 +06:00
eb3f180cc6 textSources now is main property 2021-04-27 16:08:36 +06:00
70f96ac8fa completing of captioned input deprecation 2021-04-26 21:34:13 +06:00
d69b2e09d5 migration from CaptionedInput 2021-04-26 21:25:52 +06:00
946b0222df fix botaction tests 2021-04-26 21:10:38 +06:00
7da315dbaf fix botaction tests 2021-04-26 21:08:52 +06:00
87071ca52c deprecation of an old record audio and upload audio bot actions 2021-04-26 21:02:11 +06:00
b2770e3ecc record_voice and upload_voice 2021-04-26 20:52:20 +06:00
df63ccfe07 VoiceChatScheduled 2021-04-26 20:47:03 +06:00
694bec22a2 include chat_type 2021-04-26 20:42:26 +06:00
6a3588bb8d InputInvoiceMessageContent 2021-04-26 20:23:26 +06:00
a26568aa29 maxTipAmounts and suggestedTipAmounts support in SendInvoice 2021-04-26 20:01:14 +06:00
cd30660256 update SendInvoice 2021-04-26 19:28:19 +06:00
1846d20b0d start 0.34.0 2021-04-26 19:15:55 +06:00
f13207064e Merge pull request #361 from InsanusMokrassar/0.33.4
0.33.4
2021-04-17 16:02:14 +06:00
61be689aca fix of build 2021-04-17 14:36:23 +06:00
03f8d65bb6 fix of build 2021-04-17 11:14:35 +06:00
2dc8beba8a update classcasts 2021-04-16 22:00:45 +06:00
5451adf4ac FromUserMessage extends Message 2021-04-16 18:07:27 +06:00
9982534001 updates in TextSourceSerializer 2021-04-15 14:34:05 +06:00
c0451d4c8f Update gradle-wrapper.properties 2021-04-15 13:56:52 +06:00
a9d65944e6 update MicroUtils 2021-04-13 15:53:35 +06:00
39598dcb69 fill CHANGELOG 2021-04-13 01:54:45 +06:00
3069a6084c fixes in parseCommandsWithParams 2021-04-13 01:50:41 +06:00
e7bbce3fa7 update uuid dependency 2021-04-12 23:32:50 +06:00
0b361163f2 TextSourceSerializer 2021-04-12 23:23:18 +06:00
6aba2ff641 start 0.33.4 2021-04-12 20:57:12 +06:00
6b761ab37d Update gradle wrapper 2021-04-11 04:06:30 +06:00
b9c8a89af9 Merge pull request #357 from InsanusMokrassar/0.33.3
0.33.3
2021-04-05 19:41:52 +06:00
a42c5c63c4 fillup changelog 2021-04-05 19:08:12 +06:00
fc1a029acb fix of #358 2021-04-05 19:06:49 +06:00
f90ae2f918 include weakLaunch in behaviour builder 2021-04-05 18:15:10 +06:00
019b260888 update ktor 2021-04-05 18:11:29 +06:00
0831f2fa75 update microutils 2021-04-05 17:21:59 +06:00
32ae9d2b16 hotfix 2021-04-05 16:50:31 +06:00
b975a1b036 updates in behaviour builder 2021-04-05 16:41:27 +06:00
f4b1e4a150 start 0.33.3 2021-04-05 13:42:48 +06:00
97031512d4 Merge pull request #356 from InsanusMokrassar/0.33.2
0.33.2
2021-04-03 15:39:14 +06:00
120 changed files with 1133 additions and 514 deletions

View File

@@ -1,5 +1,69 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 0.34.1
* `Common`:
* `Version`:
* `ktor`: `1.5.3` -> `1.5.4`
* `MicroUtils`: `0.4.35` -> `0.4.36`
* `Core`
* Fix in creating of text sources list
## 0.34.0
_**It is recommended to use [0.34.1](https://github.com/InsanusMokrassar/TelegramBotAPI/releases/tag/0.34.1) version due to the bug in 0.34.0 related to rewriting of `TextSource`s creating mechanism.**_
**UPDATE UP TO Telegram Bot API 5.2**
_**ALL OLD DEPRECATIONS WERE REMOVED**_
* `Core`:
* Type `ChatType` has been added
* New `ExtendedChat` for unknown messages `UnknownExtendedChat` has been added
* `SendInvoice#startParameter` becomes optional and replaced in `SendInvoice` constructor
* New interface `CommonSendInvoiceData` has been added
* Fields `CommonSendInvoiceData#maxTipAmount` and `CommonSendInvoiceData#suggestedTipAmounts` have been added
* New type `InputInvoiceMessageContent` has been added
* New interface `TextedWithTextSources` on top of `Texted` interface
* Interface `TextedInput` now extends `TextedWithTextSources` with overriding of `textSources` field as not
nullable
* `textSources` become main field in `TextedInput`
* **MIGRATION** Remove all `import dev.inmo.tgbotapi.CommonAbstracts.textSources` in your project
* `textEntities` become are calculable property in `TextedInput`
* Interface `Captioned` and `CaptionedInput` now is deprecated
* Most of captions usages were replaced with texts
* Interface `Explained` and `ExplainedInput` now is deprecated
* Most of captions usages were replaced with texts
* Interface `VoiceChatEvent` now is `CommonEvent`
* Mechanism of `RawMessageEntity` converting were fully rewritten
## 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 ## 0.33.2
* `Common`: * `Common`:

View File

@@ -18,6 +18,17 @@ plugins {
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" apply false 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() { private String getCurrentVersionChangelog() {
OutputStream changelogDataOS = new ByteArrayOutputStream() OutputStream changelogDataOS = new ByteArrayOutputStream()
exec { exec {

View File

@@ -1,3 +1,3 @@
dokka_version=1.4.30 dokka_version=1.4.32
org.gradle.jvmargs=-Xmx1024m org.gradle.jvmargs=-Xmx1024m

View File

@@ -9,14 +9,14 @@ kotlin_version=1.4.32
kotlin_coroutines_version=1.4.3 kotlin_coroutines_version=1.4.3
kotlin_serialisation_runtime_version=1.1.0 kotlin_serialisation_runtime_version=1.1.0
klock_version=2.0.7 klock_version=2.0.7
uuid_version=0.2.3 uuid_version=0.2.4
ktor_version=1.5.2 ktor_version=1.5.4
micro_utils_version=0.4.32 micro_utils_version=0.4.36
javax_activation_version=1.1.1 javax_activation_version=1.1.1
library_group=dev.inmo library_group=dev.inmo
library_version=0.33.2 library_version=0.34.1
github_release_plugin_version=2.2.12 github_release_plugin_version=2.2.12

View File

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

View File

@@ -1,6 +1,5 @@
# TelegramBotAPI Core # TelegramBotAPI Core
[![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.core/images/download.svg) ](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.core/_latestVersion)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core)
## What is it? ## What is it?
@@ -10,7 +9,7 @@ moments are describing by official [Telegram Bot API](https://core.telegram.org/
## Compatibility ## Compatibility
This version compatible with [9th of March 2021 update of TelegramBotAPI (version 5.1)](https://core.telegram.org/bots/api-changelog#march-9-2021). This version compatible with [26th of April 2021 update of TelegramBotAPI (version 5.2)](https://core.telegram.org/bots/api-changelog#april-26-2021).
## How to implement library? ## How to implement library?

View File

@@ -52,6 +52,7 @@ kotlin {
api "dev.inmo:micro_utils.coroutines:$micro_utils_version" 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.base64:$micro_utils_version"
api "dev.inmo:micro_utils.serialization.encapsulator:$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" api "io.ktor:ktor-client-core:$ktor_version"
} }

View File

@@ -1,26 +1,20 @@
package dev.inmo.tgbotapi.CommonAbstracts package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode const val CaptionDeprecation = "Captioned interface and others will be removed soon and not recommended to use"
interface Captioned { @Deprecated(CaptionDeprecation)
interface Captioned : Texted {
@Deprecated(CaptionDeprecation)
val caption: String? val caption: String?
get() = text
} }
@Deprecated("This interface is not used in library and will be removed soon") @Deprecated(CaptionDeprecation)
interface CaptionedOutput : Captioned { interface CaptionedInput : Captioned, TextedInput {
val parseMode: ParseMode?
}
interface CaptionedInput : Captioned {
/** /**
* Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] * Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
*/ */
@Deprecated(CaptionDeprecation)
val captionEntities: List<TextPart> val captionEntities: List<TextPart>
get() = textEntities
} }
/**
* @see CaptionedInput.captionEntities
* @see justTextSources
*/
val CaptionedInput.textSources
get() = captionEntities.justTextSources()

View File

@@ -0,0 +1,36 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.payments.abstracts.Currencied
import dev.inmo.tgbotapi.types.payments.abstracts.Priced
interface CommonSendInvoiceData : Titled, Currencied, Priced {
val description: String
val payload: String
val providerToken: String
val maxTipAmount: Int?
val suggestedTipAmounts: List<Int>?
val providerData: String?
val requireName: Boolean
val requirePhoneNumber: Boolean
val requireEmail: Boolean
val requireShippingAddress: Boolean
val shouldSendPhoneNumberToProvider: Boolean
val shouldSendEmailToProvider: Boolean
val priceDependOnShipAddress: Boolean
val photoUrl: String?
val photoSize: Long?
val photoWidth: Int?
val photoHeight: Int?
fun setPhoto(
photoUrl: String,
photoSize: Long? = null,
photoWidth: Int? = null,
photoHeight: Int? = null
)
fun unsetPhoto()
}

View File

@@ -1,31 +1,26 @@
package dev.inmo.tgbotapi.CommonAbstracts package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode @Deprecated("Will be removed soon")
interface Explained : Texted {
interface Explained {
val explanation: String? val explanation: String?
get() = text
} }
interface ParsableExplainedOutput : Explained { @Deprecated("Will be removed soon")
val parseMode: ParseMode? interface ParsableExplainedOutput : Explained, TextedOutput
}
interface EntitiesExplainedOutput : Explained { @Deprecated("Will be removed soon")
val entities: List<TextSource>? interface EntitiesExplainedOutput : Explained, EntitiesOutput
}
@Deprecated("Will be removed soon")
interface ExplainedOutput : ParsableExplainedOutput, EntitiesExplainedOutput interface ExplainedOutput : ParsableExplainedOutput, EntitiesExplainedOutput
@Deprecated("Will be removed soon")
interface ExplainedInput : Explained { interface ExplainedInput : Explained {
val textSources: TextSourcesList
/** /**
* Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] * Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
*/ */
val explanationEntities: List<TextPart> val explanationEntities: List<TextPart>
get() = textSources.toTextParts()
} }
/**
* @see ExplainedInput.explanationEntities
* @see justTextSources
*/
val ExplainedInput.textSources
get() = explanationEntities.justTextSources()

View File

@@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.User
interface FromUser {
val user: User
}

View File

@@ -1,14 +1,16 @@
package dev.inmo.tgbotapi.CommonAbstracts 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.textsources.regular
import dev.inmo.tgbotapi.types.MessageEntity.toTextParts
import dev.inmo.tgbotapi.types.captionLength import dev.inmo.tgbotapi.types.captionLength
import dev.inmo.tgbotapi.types.textLength 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" const val DirectInvocationOfTextSourceConstructor = "It is strongly not recommended to use constructors directly instead of factory methods"
typealias TextSourcesList = List<TextSource> typealias TextSourcesList = List<TextSource>
@Serializable(TextSourceSerializer::class)
interface TextSource { interface TextSource {
val markdown: String val markdown: String
val markdownV2: String val markdownV2: String
@@ -17,6 +19,10 @@ interface TextSource {
val asText: String val asText: String
get() = source get() = source
companion object {
fun serializer() = TextSourceSerializer
}
} }
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
@@ -28,18 +34,36 @@ inline operator fun TextSource.plus(text: String) = listOf(this, regular(text))
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
inline operator fun List<TextSource>.plus(text: String) = this + regular(text) inline operator fun List<TextSource>.plus(text: String) = this + regular(text)
@Serializable(TextSourceSerializer::class)
interface MultilevelTextSource : TextSource { interface MultilevelTextSource : TextSource {
val subsources: List<TextSource> val subsources: List<TextSource>
companion object {
fun serializer() = TextSourceSerializer
}
} }
@Deprecated("This class will be removed soon. Use TextSources instead")
data class TextPart( data class TextPart(
val range: IntRange, val range: IntRange,
val source: TextSource val source: TextSource
) )
@Deprecated("This method is no longer required to work with TextSources")
fun List<TextPart>.justTextSources() = map { it.source } fun List<TextPart>.justTextSources() = map { it.source }
internal fun List<TextSource>.toTextParts(preOffset: Int = 0): List<TextPart> {
var i = preOffset
return map {
TextPart(
i until (i + it.source.length),
it
).also {
i = it.range.last + 1
}
}
}
fun List<TextSource>.makeString() = joinToString("") { it.source } fun List<TextSource>.makeString() = joinToString("") { it.source }
internal fun MultilevelTextSource.textParts(offset: Int): List<TextPart> = subsources.toTextParts(offset)
fun List<TextSource>.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List<List<TextSource>> { fun List<TextSource>.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List<List<TextSource>> {
if (isEmpty()) { if (isEmpty()) {
return emptyList() return emptyList()

View File

@@ -5,31 +5,31 @@ import dev.inmo.tgbotapi.types.ParseMode.ParseMode
interface Texted { interface Texted {
val text: String? val text: String?
} }
interface TextedWithTextSources : Texted {
/**
* Full list of [TextSource] built from source[TextedInput.textEntities]
*/
val textSources: List<TextSource>?
}
interface ParsableOutput : Texted { interface ParsableOutput : Texted {
val parseMode: ParseMode? val parseMode: ParseMode?
} }
interface EntitiesOutput : Texted { interface EntitiesOutput : TextedWithTextSources {
val entities: List<TextSource>? val entities: List<TextSource>?
get() = textSources
} }
interface TextedOutput : ParsableOutput, EntitiesOutput interface TextedOutput : ParsableOutput, EntitiesOutput
interface TextedInput : Texted { interface TextedInput : TextedWithTextSources {
override val textSources: List<TextSource>
/** /**
* Here must be full list of entities. This list must contains [TextPart]s with * Here must be full list of entities. This list must contains [TextPart]s with
* [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] in case if source text contains parts of * [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] in case if source text contains parts of
* regular text * regular text
*/ */
val textEntities: List<TextPart> val textEntities: List<TextPart>
get() = textSources.toTextParts()
} }
/**
* Full list of [TextSource] built from source[TextedInput.textEntities]
*
* @see TextedInput.textEntities
* @see justTextSources
*/
val TextedInput.textSources
get() = textEntities.justTextSources()

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.edit.caption package dev.inmo.tgbotapi.requests.edit.caption
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.requests.edit.media.MediaContentMessageResultDeserializer import dev.inmo.tgbotapi.requests.edit.media.MediaContentMessageResultDeserializer
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -58,8 +59,8 @@ data class EditChatMessageCaption internal constructor(
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : EditChatMessage<MediaContent>, EditTextChatMessage, EditReplyMessage { ) : EditChatMessage<MediaContent>, EditTextChatMessage, EditReplyMessage {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources() rawEntities ?.asTextSources(text)
} }
override fun method(): String = editMessageCaptionMethod override fun method(): String = editMessageCaptionMethod

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.edit.caption package dev.inmo.tgbotapi.requests.edit.caption
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.* import dev.inmo.tgbotapi.types.MessageEntity.*
@@ -47,8 +48,8 @@ data class EditInlineMessageCaption internal constructor(
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage { ) : EditInlineMessage, EditTextChatMessage, EditReplyMessage {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources() rawEntities ?.asTextSources(text)
} }
override fun method(): String = editMessageCaptionMethod override fun method(): String = editMessageCaptionMethod

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.edit.text package dev.inmo.tgbotapi.requests.edit.text
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.requests.send.TextContentMessageResultDeserializer import dev.inmo.tgbotapi.requests.send.TextContentMessageResultDeserializer
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -64,8 +65,8 @@ data class EditChatMessageText internal constructor(
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : EditChatMessage<TextContent>, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage { ) : EditChatMessage<TextContent>, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources() rawEntities ?.asTextSources(text)
} }
override fun method(): String = editMessageTextMethod override fun method(): String = editMessageTextMethod

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.edit.text package dev.inmo.tgbotapi.requests.edit.text
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.* import dev.inmo.tgbotapi.types.MessageEntity.*
@@ -53,8 +54,8 @@ data class EditInlineMessageText internal constructor(
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage { ) : EditInlineMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources() rawEntities ?.asTextSources(text)
} }
override fun method(): String = editMessageTextMethod override fun method(): String = editMessageTextMethod

View File

@@ -62,8 +62,8 @@ data class CopyMessage internal constructor(
TextedOutput { TextedOutput {
override val chatId: ChatIdentifier override val chatId: ChatIdentifier
get() = fromChatId get() = fromChatId
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
override fun method(): String = "copyMessage" override fun method(): String = "copyMessage"

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.send package dev.inmo.tgbotapi.requests.send
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.CommonAbstracts.types.DisableWebPagePreview import dev.inmo.tgbotapi.CommonAbstracts.types.DisableWebPagePreview
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -83,8 +84,8 @@ data class SendTextMessage internal constructor(
TextableSendMessageRequest<ContentMessage<TextContent>>, TextableSendMessageRequest<ContentMessage<TextContent>>,
DisableWebPagePreview DisableWebPagePreview
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources() rawEntities ?.asTextSources(text)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.* import dev.inmo.tgbotapi.requests.send.media.base.*
@@ -20,7 +21,7 @@ fun SendAnimation(
chatId: ChatIdentifier, chatId: ChatIdentifier,
animation: InputFile, animation: InputFile,
thumb: InputFile? = null, thumb: InputFile? = null,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
duration: Long? = null, duration: Long? = null,
width: Int? = null, width: Int? = null,
@@ -39,7 +40,7 @@ fun SendAnimation(
chatId, chatId,
animationAsFileId, animationAsFileId,
thumbAsFileId, thumbAsFileId,
caption, text,
parseMode, parseMode,
null, null,
duration, duration,
@@ -144,8 +145,8 @@ data class SendAnimationData internal constructor(
DuratedSendMessageRequest<ContentMessage<AnimationContent>>, DuratedSendMessageRequest<ContentMessage<AnimationContent>>,
SizedSendMessageRequest<ContentMessage<AnimationContent>> SizedSendMessageRequest<ContentMessage<AnimationContent>>
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -20,7 +20,7 @@ fun SendAudio(
chatId: ChatIdentifier, chatId: ChatIdentifier,
audio: InputFile, audio: InputFile,
thumb: InputFile? = null, thumb: InputFile? = null,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
duration: Long? = null, duration: Long? = null,
performer: String? = null, performer: String? = null,
@@ -39,7 +39,7 @@ fun SendAudio(
chatId, chatId,
audioAsFileId, audioAsFileId,
thumbAsFileId, thumbAsFileId,
caption, text,
parseMode, parseMode,
null, null,
duration, duration,
@@ -145,8 +145,8 @@ data class SendAudioData internal constructor(
DuratedSendMessageRequest<ContentMessage<AudioContent>>, DuratedSendMessageRequest<ContentMessage<AudioContent>>,
Performerable Performerable
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.* import dev.inmo.tgbotapi.requests.send.media.base.*
@@ -29,7 +30,7 @@ fun SendDocument(
chatId: ChatIdentifier, chatId: ChatIdentifier,
document: InputFile, document: InputFile,
thumb: InputFile? = null, thumb: InputFile? = null,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
@@ -46,7 +47,7 @@ fun SendDocument(
chatId, chatId,
documentAsFileId, documentAsFileId,
thumbAsFileId, thumbAsFileId,
caption, text,
parseMode, parseMode,
null, null,
disableNotification, disableNotification,
@@ -157,8 +158,8 @@ data class SendDocumentData internal constructor(
TextableSendMessageRequest<ContentMessage<DocumentContent>>, TextableSendMessageRequest<ContentMessage<DocumentContent>>,
ThumbedSendMessageRequest<ContentMessage<DocumentContent>> ThumbedSendMessageRequest<ContentMessage<DocumentContent>>
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.* import dev.inmo.tgbotapi.requests.send.media.base.*
@@ -18,7 +19,7 @@ import kotlinx.serialization.*
fun SendPhoto( fun SendPhoto(
chatId: ChatIdentifier, chatId: ChatIdentifier,
photo: InputFile, photo: InputFile,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
@@ -28,7 +29,7 @@ fun SendPhoto(
val data = SendPhotoData( val data = SendPhotoData(
chatId, chatId,
(photo as? FileId) ?.fileId, (photo as? FileId) ?.fileId,
caption, text,
parseMode, parseMode,
null, null,
disableNotification, disableNotification,
@@ -100,8 +101,8 @@ data class SendPhotoData internal constructor(
ReplyingMarkupSendMessageRequest<ContentMessage<PhotoContent>>, ReplyingMarkupSendMessageRequest<ContentMessage<PhotoContent>>,
TextableSendMessageRequest<ContentMessage<PhotoContent>> TextableSendMessageRequest<ContentMessage<PhotoContent>>
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.* import dev.inmo.tgbotapi.requests.send.media.base.*
@@ -20,7 +21,7 @@ fun SendVideo(
chatId: ChatIdentifier, chatId: ChatIdentifier,
video: InputFile, video: InputFile,
thumb: InputFile? = null, thumb: InputFile? = null,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
duration: Long? = null, duration: Long? = null,
width: Int? = null, width: Int? = null,
@@ -40,7 +41,7 @@ fun SendVideo(
chatId, chatId,
videoAsFileId, videoAsFileId,
thumbAsFileId, thumbAsFileId,
caption, text,
parseMode, parseMode,
null, null,
duration, duration,
@@ -150,8 +151,8 @@ data class SendVideoData internal constructor(
DuratedSendMessageRequest<ContentMessage<VideoContent>>, DuratedSendMessageRequest<ContentMessage<VideoContent>>,
SizedSendMessageRequest<ContentMessage<VideoContent>> SizedSendMessageRequest<ContentMessage<VideoContent>>
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.* import dev.inmo.tgbotapi.requests.send.media.base.*
@@ -19,7 +20,7 @@ import kotlinx.serialization.*
fun SendVoice( fun SendVoice(
chatId: ChatIdentifier, chatId: ChatIdentifier,
voice: InputFile, voice: InputFile,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
duration: Long? = null, duration: Long? = null,
disableNotification: Boolean = false, disableNotification: Boolean = false,
@@ -33,7 +34,7 @@ fun SendVoice(
val data = SendVoiceData( val data = SendVoiceData(
chatId, chatId,
voiceAsFileId, voiceAsFileId,
caption, text,
parseMode, parseMode,
null, null,
duration, duration,
@@ -120,8 +121,8 @@ data class SendVoiceData internal constructor(
TextableSendMessageRequest<ContentMessage<VoiceContent>>, TextableSendMessageRequest<ContentMessage<VoiceContent>>,
DuratedSendMessageRequest<ContentMessage<VoiceContent>> DuratedSendMessageRequest<ContentMessage<VoiceContent>>
{ {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.requests.send.payments package dev.inmo.tgbotapi.requests.send.payments
import dev.inmo.tgbotapi.CommonAbstracts.CommonSendInvoiceData
import dev.inmo.tgbotapi.CommonAbstracts.types.* import dev.inmo.tgbotapi.CommonAbstracts.types.*
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -9,7 +10,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializ
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
import dev.inmo.tgbotapi.types.payments.LabeledPrice import dev.inmo.tgbotapi.types.payments.LabeledPrice
import dev.inmo.tgbotapi.types.payments.LabeledPricesSerializer import dev.inmo.tgbotapi.types.payments.LabeledPricesSerializer
import dev.inmo.tgbotapi.types.payments.abstracts.* import dev.inmo.tgbotapi.types.payments.abstracts.Currency
import kotlinx.serialization.* import kotlinx.serialization.*
private val invoiceMessageSerializer: DeserializationStrategy<ContentMessage<InvoiceContent>> private val invoiceMessageSerializer: DeserializationStrategy<ContentMessage<InvoiceContent>>
@@ -23,36 +24,40 @@ data class SendInvoice(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatId, override val chatId: ChatId,
@SerialName(titleField) @SerialName(titleField)
val title: String, override val title: String,
@SerialName(descriptionField) @SerialName(descriptionField)
val description: String, override val description: String,
@SerialName(payloadField) @SerialName(payloadField)
val payload: String, override val payload: String,
@SerialName(providerTokenField) @SerialName(providerTokenField)
val providerToken: String, override val providerToken: String,
@SerialName(startParameterField)
val startParameter: StartParameter,
@SerialName(currencyField) @SerialName(currencyField)
override val currency: Currency, override val currency: Currency,
@Serializable(LabeledPricesSerializer::class) @Serializable(LabeledPricesSerializer::class)
@SerialName(pricesField) @SerialName(pricesField)
override val prices: List<LabeledPrice>, override val prices: List<LabeledPrice>,
@SerialName(maxTipAmountField)
override val maxTipAmount: Int? = null,
@SerialName(suggestedTipAmountsField)
override val suggestedTipAmounts: List<Int>? = null,
@SerialName(startParameterField)
val startParameter: StartParameter? = null,
@SerialName(providerDataField) @SerialName(providerDataField)
val providerData: String? = null, override val providerData: String? = null,
@SerialName(requireNameField) @SerialName(requireNameField)
val requireName: Boolean = false, override val requireName: Boolean = false,
@SerialName(requirePhoneNumberField) @SerialName(requirePhoneNumberField)
val requirePhoneNumber: Boolean = false, override val requirePhoneNumber: Boolean = false,
@SerialName(requireEmailField) @SerialName(requireEmailField)
val requireEmail: Boolean = false, override val requireEmail: Boolean = false,
@SerialName(requireShippingAddressField) @SerialName(requireShippingAddressField)
val requireShippingAddress: Boolean = false, override val requireShippingAddress: Boolean = false,
@SerialName(shouldSendPhoneNumberToProviderField) @SerialName(shouldSendPhoneNumberToProviderField)
val shouldSendPhoneNumberToProvider: Boolean = false, override val shouldSendPhoneNumberToProvider: Boolean = false,
@SerialName(shouldSendEmailToProviderField) @SerialName(shouldSendEmailToProviderField)
val shouldSendEmailToProvider: Boolean = false, override val shouldSendEmailToProvider: Boolean = false,
@SerialName(priceDependOnShipAddressField) @SerialName(priceDependOnShipAddressField)
val priceDependOnShipAddress: Boolean = false, override val priceDependOnShipAddress: Boolean = false,
@SerialName(disableNotificationField) @SerialName(disableNotificationField)
override val disableNotification: Boolean = false, override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField) @SerialName(replyToMessageIdField)
@@ -61,8 +66,7 @@ data class SendInvoice(
override val allowSendingWithoutReply: Boolean? = null, override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : Currencied, ) : CommonSendInvoiceData,
Priced,
ChatRequest, ChatRequest,
DisableNotification, DisableNotification,
ReplyMessageId, ReplyMessageId,
@@ -75,24 +79,35 @@ data class SendInvoice(
get() = serializer() get() = serializer()
@SerialName(photoUrlField) @SerialName(photoUrlField)
var photoUrl: String? = null override var photoUrl: String? = null
private set private set
@SerialName(photoSizeField) @SerialName(photoSizeField)
var photoSize: Long? = null override var photoSize: Long? = null
private set private set
@SerialName(photoWidthField) @SerialName(photoWidthField)
var photoWidth: Int? = null override var photoWidth: Int? = null
private set private set
@SerialName(photoHeightField) @SerialName(photoHeightField)
var photoHeight: Int? = null override var photoHeight: Int? = null
private set private set
fun setPhoto( init {
suggestedTipAmounts ?.let { _ ->
require(suggestedTipAmounts.size in suggestedTipAmountsLimit)
maxTipAmount ?.let { _ ->
require(
suggestedTipAmounts.none { it > maxTipAmount }
)
}
}
}
override fun setPhoto(
photoUrl: String, photoUrl: String,
photoSize: Long? = null, photoSize: Long?,
photoWidth: Int? = null, photoWidth: Int?,
photoHeight: Int? = null photoHeight: Int?
) { ) {
this.photoUrl = photoUrl this.photoUrl = photoUrl
this.photoSize = photoSize this.photoSize = photoSize
@@ -100,7 +115,7 @@ data class SendInvoice(
this.photoHeight = photoHeight this.photoHeight = photoHeight
} }
fun unsetPhoto() { override fun unsetPhoto() {
photoUrl = null photoUrl = null
photoSize = null photoSize = null
photoWidth = null photoWidth = null

View File

@@ -338,7 +338,7 @@ data class SendQuizPoll internal constructor(
@SerialName(isClosedField) @SerialName(isClosedField)
override val isClosed: Boolean = false, override val isClosed: Boolean = false,
@SerialName(explanationField) @SerialName(explanationField)
override val explanation: String? = null, override val text: String? = null,
@SerialName(explanationParseModeField) @SerialName(explanationParseModeField)
override val parseMode: ParseMode? = null, override val parseMode: ParseMode? = null,
@SerialName(explanationEntitiesField) @SerialName(explanationEntitiesField)
@@ -355,12 +355,12 @@ data class SendQuizPoll internal constructor(
override val allowSendingWithoutReply: Boolean? = null, override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null override val replyMarkup: KeyboardMarkup? = null
) : SendPoll(), ExplainedOutput { ) : SendPoll(), ExplainedOutput, TextedOutput {
override val type: String = quizPollType override val type: String = quizPollType
override val requestSerializer: SerializationStrategy<*> override val requestSerializer: SerializationStrategy<*>
get() = serializer() get() = serializer()
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(explanation ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {
@@ -371,9 +371,9 @@ data class SendQuizPoll internal constructor(
throw IllegalArgumentException("Correct option id must be in range of $correctOptionIdRange, but actual " + throw IllegalArgumentException("Correct option id must be in range of $correctOptionIdRange, but actual " +
"value is $correctOptionId") "value is $correctOptionId")
} }
if (explanation != null && explanation.length !in explanationLimit) { if (text != null && text.length !in explanationLimit) {
error("Quiz poll explanation size must be in range $explanationLimit," + error("Quiz poll explanation size must be in range $explanationLimit," +
"but actual explanation contains ${explanation.length} symbols") "but actual explanation contains ${text.length} symbols")
} }
} }
} }

View File

@@ -80,6 +80,10 @@ val openPeriodPollSecondsLimit = 5 .. 600
val membersLimit = 1 .. 99999 val membersLimit = 1 .. 99999
val suggestedTipAmountsLimit = 1 .. 4
const val botActionActualityTime: Seconds = 5
// Made as lazy for correct work in K/JS // Made as lazy for correct work in K/JS
val telegramInlineModeGifPermittedMimeTypes by lazy { val telegramInlineModeGifPermittedMimeTypes by lazy {
listOf( listOf(
@@ -313,6 +317,10 @@ const val xShiftField = "x_shift"
const val yShiftField = "y_shift" const val yShiftField = "y_shift"
const val scaleField = "scale" const val scaleField = "scale"
const val maxTipAmountField = "max_tip_amount"
const val suggestedTipAmountsField = "suggested_tip_amounts"
const val chatTypeField = "chat_type"
const val explanationEntitiesField = "explanation_entities" const val explanationEntitiesField = "explanation_entities"
const val explanationParseModeField = "explanation_parse_mode" const val explanationParseModeField = "explanation_parse_mode"
const val openPeriodField = "open_period" const val openPeriodField = "open_period"
@@ -347,6 +355,7 @@ const val providerPaymentChargeIdField = "provider_payment_charge_id"
const val providerTokenField = "provider_token" const val providerTokenField = "provider_token"
const val providerDataField = "provider_data" const val providerDataField = "provider_data"
const val usersField = "users" const val usersField = "users"
const val startDateField = "start_date"
const val requireNameField = "need_name" const val requireNameField = "need_name"
const val requirePhoneNumberField = "need_phone_number" const val requirePhoneNumberField = "need_phone_number"

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.audio.InlineQueryResultAudioCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio.InlineQueryResultAudioCached
@@ -48,7 +49,7 @@ data class InlineQueryResultAudioCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultAudioCached { ) : InlineQueryResultAudioCached {
override val type: String = inlineQueryResultAudioType override val type: String = inlineQueryResultAudioType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio.InlineQueryResultAudio import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio.InlineQueryResultAudio
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio.inlineQueryResultAudioType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio.inlineQueryResultAudioType
@@ -59,7 +60,7 @@ data class InlineQueryResultAudioImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultAudio { ) : InlineQueryResultAudio {
override val type: String = inlineQueryResultAudioType override val type: String = inlineQueryResultAudioType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.document.InlineQueryResultDocumentCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document.InlineQueryResultDocumentCached
@@ -56,7 +57,7 @@ data class InlineQueryResultDocumentCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultDocumentCached { ) : InlineQueryResultDocumentCached {
override val type: String = inlineQueryResultDocumentType override val type: String = inlineQueryResultDocumentType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document.InlineQueryResultDocument import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document.InlineQueryResultDocument
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document.inlineQueryResultDocumentType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document.inlineQueryResultDocumentType
@@ -73,7 +74,7 @@ data class InlineQueryResultDocumentImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultDocument { ) : InlineQueryResultDocument {
override val type: String = inlineQueryResultDocumentType override val type: String = inlineQueryResultDocumentType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.gif.InlineQueryResultGifCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif.InlineQueryResultGifCached
@@ -52,7 +53,7 @@ data class InlineQueryResultGifCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultGifCached { ) : InlineQueryResultGifCached {
override val type: String = inlineQueryResultGifType override val type: String = inlineQueryResultGifType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif.InlineQueryResultGif import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif.InlineQueryResultGif
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif.inlineQueryResultGifType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif.inlineQueryResultGifType
@@ -72,8 +73,8 @@ data class InlineQueryResultGifImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultGif { ) : InlineQueryResultGif {
override val type: String = inlineQueryResultGifType override val type: String = inlineQueryResultGifType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif.InlineQueryResultMpeg4GifCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif.InlineQueryResultMpeg4GifCached
@@ -52,7 +53,7 @@ data class InlineQueryResultMpeg4GifCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultMpeg4GifCached { ) : InlineQueryResultMpeg4GifCached {
override val type: String = inlineQueryResultMpeg4GifType override val type: String = inlineQueryResultMpeg4GifType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif.InlineQueryResultMpeg4Gif import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif.InlineQueryResultMpeg4Gif
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif.inlineQueryResultMpeg4GifType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif.inlineQueryResultMpeg4GifType
@@ -72,8 +73,8 @@ data class InlineQueryResultMpeg4GifImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultMpeg4Gif { ) : InlineQueryResultMpeg4Gif {
override val type: String = inlineQueryResultMpeg4GifType override val type: String = inlineQueryResultMpeg4GifType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
init { init {

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.photo.InlineQueryResultPhotoCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo.InlineQueryResultPhotoCached
@@ -56,7 +57,7 @@ data class InlineQueryResultPhotoCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultPhotoCached { ) : InlineQueryResultPhotoCached {
override val type: String = inlineQueryResultPhotoType override val type: String = inlineQueryResultPhotoType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo.InlineQueryResultPhoto import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo.InlineQueryResultPhoto
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo.inlineQueryResultPhotoType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo.inlineQueryResultPhotoType
@@ -67,7 +68,7 @@ data class InlineQueryResultPhotoImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultPhoto { ) : InlineQueryResultPhoto {
override val type: String = inlineQueryResultPhotoType override val type: String = inlineQueryResultPhotoType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.video.InlineQueryResultVideoCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video.InlineQueryResultVideoCached
@@ -56,7 +57,7 @@ data class InlineQueryResultVideoCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVideoCached { ) : InlineQueryResultVideoCached {
override val type: String = inlineQueryResultVideoType override val type: String = inlineQueryResultVideoType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video.InlineQueryResultVideo import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video.InlineQueryResultVideo
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video.inlineQueryResultVideoType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video.inlineQueryResultVideoType
@@ -77,7 +78,7 @@ data class InlineQueryResultVideoImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVideo { ) : InlineQueryResultVideo {
override val type: String = inlineQueryResultVideoType override val type: String = inlineQueryResultVideoType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
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.InlineQueries.InlineQueryResult.abstracts.results.voice.InlineQueryResultVoiceCached import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.InlineQueryResultVoiceCached
@@ -52,7 +53,7 @@ data class InlineQueryResultVoiceCachedImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVoiceCached { ) : InlineQueryResultVoiceCached {
override val type: String = inlineQueryResultVoiceType override val type: String = inlineQueryResultVoiceType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.InlineQueryResultVoice import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.InlineQueryResultVoice
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.inlineQueryResultVoiceType import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.inlineQueryResultVoiceType
@@ -65,7 +66,7 @@ data class InlineQueryResultVoiceImpl internal constructor(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVoice { ) : InlineQueryResultVoice {
override val type: String = inlineQueryResultVoiceType override val type: String = inlineQueryResultVoiceType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
} }

View File

@@ -0,0 +1,80 @@
package dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent
import dev.inmo.tgbotapi.CommonAbstracts.CommonSendInvoiceData
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.payments.LabeledPrice
import dev.inmo.tgbotapi.types.payments.LabeledPricesSerializer
import dev.inmo.tgbotapi.types.payments.abstracts.Currency
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
class InputInvoiceMessageContent(
@SerialName(titleField)
override val title: String,
@SerialName(descriptionField)
override val description: String,
@SerialName(payloadField)
override val payload: String,
@SerialName(providerTokenField)
override val providerToken: String,
@SerialName(currencyField)
override val currency: Currency,
@Serializable(LabeledPricesSerializer::class)
@SerialName(pricesField)
override val prices: List<LabeledPrice>,
@SerialName(maxTipAmountField)
override val maxTipAmount: Int? = null,
@SerialName(suggestedTipAmountsField)
override val suggestedTipAmounts: List<Int>? = null,
@SerialName(providerDataField)
override val providerData: String? = null,
@SerialName(requireNameField)
override val requireName: Boolean = false,
@SerialName(requirePhoneNumberField)
override val requirePhoneNumber: Boolean = false,
@SerialName(requireEmailField)
override val requireEmail: Boolean = false,
@SerialName(requireShippingAddressField)
override val requireShippingAddress: Boolean = false,
@SerialName(shouldSendPhoneNumberToProviderField)
override val shouldSendPhoneNumberToProvider: Boolean = false,
@SerialName(shouldSendEmailToProviderField)
override val shouldSendEmailToProvider: Boolean = false,
@SerialName(priceDependOnShipAddressField)
override val priceDependOnShipAddress: Boolean = false
) : InputMessageContent, CommonSendInvoiceData {
@SerialName(photoUrlField)
override var photoUrl: String? = null
private set
@SerialName(photoSizeField)
override var photoSize: Long? = null
private set
@SerialName(photoWidthField)
override var photoWidth: Int? = null
private set
@SerialName(photoHeightField)
override var photoHeight: Int? = null
private set
override fun setPhoto(
photoUrl: String,
photoSize: Long?,
photoWidth: Int?,
photoHeight: Int?
) {
this.photoUrl = photoUrl
this.photoSize = photoSize
this.photoWidth = photoWidth
this.photoHeight = photoHeight
}
override fun unsetPhoto() {
photoUrl = null
photoSize = null
photoWidth = null
photoHeight = null
}
}

View File

@@ -38,7 +38,7 @@ data class InputTextMessageContent internal constructor(
@SerialName(disableWebPagePreviewField) @SerialName(disableWebPagePreviewField)
override val disableWebPagePreview: Boolean? = null override val disableWebPagePreview: Boolean? = null
) : TextedOutput, DisableWebPagePreview, InputMessageContent { ) : TextedOutput, DisableWebPagePreview, InputMessageContent {
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources() rawEntities ?.asTextSources(text)
} }
} }

View File

@@ -17,6 +17,7 @@ internal object InputMessageContentSerializer : KSerializer<InputMessageContent>
is InputLocationMessageContent -> InputLocationMessageContent.serializer().serialize(encoder, value) is InputLocationMessageContent -> InputLocationMessageContent.serializer().serialize(encoder, value)
is InputTextMessageContent -> InputTextMessageContent.serializer().serialize(encoder, value) is InputTextMessageContent -> InputTextMessageContent.serializer().serialize(encoder, value)
is InputVenueMessageContent -> InputVenueMessageContent.serializer().serialize(encoder, value) is InputVenueMessageContent -> InputVenueMessageContent.serializer().serialize(encoder, value)
is InputInvoiceMessageContent -> InputInvoiceMessageContent.serializer().serialize(encoder, value)
else -> throw IllegalArgumentException("Unknown for serializing InputContactMessageContent") else -> throw IllegalArgumentException("Unknown for serializing InputContactMessageContent")
} }
} }

View File

@@ -2,10 +2,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.abstracts
import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.InlineQueryIdentifier
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.chat.ChatType
interface InlineQuery { interface InlineQuery {
val id: InlineQueryIdentifier val id: InlineQueryIdentifier
val from: User val from: User
val query: String val query: String
val offset: String val offset: String
val chatType: ChatType?
} }

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.InlineQueryIdentifier
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.chat.ChatType
data class BaseInlineQuery( data class BaseInlineQuery(
override val id: InlineQueryIdentifier, override val id: InlineQueryIdentifier,
override val from: User, override val from: User,
override val query: String, override val query: String,
override val offset: String override val offset: String,
override val chatType: ChatType?
) : InlineQuery ) : InlineQuery

View File

@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.InlineQueryIdentifier
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.chat.ChatType
import dev.inmo.tgbotapi.types.location.Location import dev.inmo.tgbotapi.types.location.Location
data class LocationInlineQuery( data class LocationInlineQuery(
@@ -10,5 +11,6 @@ data class LocationInlineQuery(
override val from: User, override val from: User,
override val query: String, override val query: String,
override val offset: String, override val offset: String,
override val chatType: ChatType?,
val location: Location val location: Location
) : InlineQuery ) : InlineQuery

View File

@@ -1,6 +1,8 @@
package dev.inmo.tgbotapi.types.InlineQueries.query package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.ChatType
import dev.inmo.tgbotapi.types.chat.ChatTypeSerializer
import dev.inmo.tgbotapi.types.location.Location import dev.inmo.tgbotapi.types.location.Location
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -15,12 +17,15 @@ internal data class RawInlineQuery(
val query: String, val query: String,
@SerialName(offsetField) @SerialName(offsetField)
val offset: String, val offset: String,
@SerialName(chatTypeField)
@Serializable(ChatTypeSerializer::class)
val chatType: ChatType? = null,
@SerialName(locationField) @SerialName(locationField)
val location: Location? = null val location: Location? = null
) { ) {
val asInlineQuery by lazy { val asInlineQuery by lazy {
location ?.let { location ?.let {
LocationInlineQuery(id, from, query, offset, location) LocationInlineQuery(id, from, query, offset, chatType, location)
} ?: BaseInlineQuery(id, from, query, offset) } ?: BaseInlineQuery(id, from, query, offset, chatType)
} }
} }

View File

@@ -44,8 +44,8 @@ data class InputMediaAnimation internal constructor(
override val thumb: InputFile? = null override val thumb: InputFile? = null
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, TextedOutput { ) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, TextedOutput {
override val type: String = "animation" override val type: String = "animation"
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
@SerialName(mediaField) @SerialName(mediaField)

View File

@@ -50,8 +50,8 @@ data class InputMediaAudio internal constructor(
override val thumb: InputFile? = null override val thumb: InputFile? = null
) : InputMedia, AudioMediaGroupMemberInputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, Performerable { ) : InputMedia, AudioMediaGroupMemberInputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, Performerable {
override val type: String = audioInputMediaType override val type: String = audioInputMediaType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
@@ -62,12 +62,12 @@ data class InputMediaAudio internal constructor(
} }
fun AudioFile.toInputMediaAudio( fun AudioFile.toInputMediaAudio(
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
title: String? = this.title title: String? = this.title
): InputMediaAudio = InputMediaAudio( ): InputMediaAudio = InputMediaAudio(
fileId, fileId,
caption, text,
parseMode, parseMode,
duration, duration,
performer, performer,

View File

@@ -13,11 +13,11 @@ internal const val documentInputMediaType = "document"
fun InputMediaDocument( fun InputMediaDocument(
file: InputFile, file: InputFile,
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
thumb: InputFile? = null, thumb: InputFile? = null,
disableContentTypeDetection: Boolean? = null disableContentTypeDetection: Boolean? = null
) = InputMediaDocument(file, caption, parseMode, null, thumb, disableContentTypeDetection) ) = InputMediaDocument(file, text, parseMode, null, thumb, disableContentTypeDetection)
fun InputMediaDocument( fun InputMediaDocument(
file: InputFile, file: InputFile,
@@ -50,8 +50,8 @@ data class InputMediaDocument internal constructor(
val disableContentTypeDetection: Boolean? = null val disableContentTypeDetection: Boolean? = null
) : InputMedia, DocumentMediaGroupMemberInputMedia, ThumbedInputMedia { ) : InputMedia, DocumentMediaGroupMemberInputMedia, ThumbedInputMedia {
override val type: String = documentInputMediaType override val type: String = documentInputMediaType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
@@ -62,11 +62,11 @@ data class InputMediaDocument internal constructor(
} }
fun DocumentFile.toInputMediaDocument( fun DocumentFile.toInputMediaDocument(
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null parseMode: ParseMode? = null
) = InputMediaDocument( ) = InputMediaDocument(
fileId, fileId,
caption, text,
parseMode, parseMode,
thumb ?.fileId thumb ?.fileId
) )

View File

@@ -34,8 +34,8 @@ data class InputMediaPhoto internal constructor(
private val rawEntities: List<RawMessageEntity>? = null private val rawEntities: List<RawMessageEntity>? = null
) : InputMedia, VisualMediaGroupMemberInputMedia { ) : InputMedia, VisualMediaGroupMemberInputMedia {
override val type: String = photoInputMediaType override val type: String = photoInputMediaType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
@@ -46,11 +46,11 @@ data class InputMediaPhoto internal constructor(
} }
fun PhotoSize.toInputMediaPhoto( fun PhotoSize.toInputMediaPhoto(
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null parseMode: ParseMode? = null
): InputMediaPhoto = InputMediaPhoto( ): InputMediaPhoto = InputMediaPhoto(
fileId, fileId,
caption, text,
parseMode parseMode
) )

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InputMedia package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.makeString
import dev.inmo.tgbotapi.requests.abstracts.InputFile import dev.inmo.tgbotapi.requests.abstracts.InputFile
import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -45,8 +46,8 @@ data class InputMediaVideo internal constructor (
override val thumb: InputFile? = null override val thumb: InputFile? = null
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, VisualMediaGroupMemberInputMedia { ) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, VisualMediaGroupMemberInputMedia {
override val type: String = videoInputMediaType override val type: String = videoInputMediaType
override val entities: List<TextSource>? by lazy { override val textSources: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() rawEntities ?.asTextSources(text ?: return@lazy null)
} }
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)

View File

@@ -1,10 +1,9 @@
package dev.inmo.tgbotapi.types.MessageEntity package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.MultilevelTextSource
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.types.MessageEntity.textsources.* import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.shiftSourcesToTheLeft
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@@ -15,70 +14,115 @@ internal data class RawMessageEntity(
val url: String? = null, val url: String? = null,
val user: User? = null, val user: User? = null,
val language: String? = null val language: String? = null
) ) {
internal val range by lazy {
internal fun RawMessageEntity.asTextParts( offset until (offset + length)
source: String,
subParts: List<TextPart>
): List<TextPart> {
val sourceSubstring: String = source.substring(offset, offset + length)
val range = offset until (offset + length)
val shiftedSubSources = sourceSubstring.fullListOfSubSource(subParts.shiftSourcesToTheLeft(offset)).justTextSources()
return when (type) {
"mention" -> MentionTextSource(sourceSubstring, shiftedSubSources)
"hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubSources)
"cashtag" -> CashTagTextSource(sourceSubstring, shiftedSubSources)
"bot_command" -> BotCommandTextSource(sourceSubstring)
"url" -> URLTextSource(sourceSubstring)
"email" -> EMailTextSource(sourceSubstring, shiftedSubSources)
"phone_number" -> PhoneNumberTextSource(sourceSubstring, shiftedSubSources)
"bold" -> BoldTextSource(sourceSubstring, shiftedSubSources)
"italic" -> ItalicTextSource(sourceSubstring, shiftedSubSources)
"code" -> CodeTextSource(sourceSubstring)
"pre" -> PreTextSource(sourceSubstring, language)
"text_link" -> TextLinkTextSource(sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link"))
"text_mention" -> TextMentionTextSource(sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention"), shiftedSubSources)
"underline" -> UnderlineTextSource(sourceSubstring, shiftedSubSources)
"strikethrough" -> StrikethroughTextSource(sourceSubstring, shiftedSubSources)
else -> RegularTextSource(sourceSubstring)
}.let {
val part = TextPart(range, it)
if (it !is MultilevelTextSource && subParts.isNotEmpty()) {
(subParts + part).sortedBy { currentPart -> currentPart.range.first }
} else {
listOf(part)
}
} }
} }
internal fun createTextPart(originalFullString: String, entities: RawMessageEntities): List<TextPart> { internal fun RawMessageEntity.asTextSource(
val mutableEntities = entities.toMutableList() source: String,
mutableEntities.sortBy { it.offset } subParts: List<TextSource>
val resultList = mutableListOf<TextPart>() ): TextSource {
val sourceSubstring: String = source.substring(range)
val subPartsWithRegulars by lazy {
subParts.fillWithRegulars(sourceSubstring)
}
return when (type) {
"mention" -> MentionTextSource(sourceSubstring, subPartsWithRegulars)
"hashtag" -> HashTagTextSource(sourceSubstring, subPartsWithRegulars)
"cashtag" -> CashTagTextSource(sourceSubstring, subPartsWithRegulars)
"bot_command" -> BotCommandTextSource(sourceSubstring)
"url" -> URLTextSource(sourceSubstring)
"email" -> EMailTextSource(sourceSubstring, subPartsWithRegulars)
"phone_number" -> PhoneNumberTextSource(sourceSubstring, subPartsWithRegulars)
"bold" -> BoldTextSource(sourceSubstring, subPartsWithRegulars)
"italic" -> ItalicTextSource(sourceSubstring, subPartsWithRegulars)
"code" -> CodeTextSource(sourceSubstring)
"pre" -> PreTextSource(sourceSubstring, language)
"text_link" -> TextLinkTextSource(sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link"))
"text_mention" -> TextMentionTextSource(sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention"), subPartsWithRegulars)
"underline" -> UnderlineTextSource(sourceSubstring, subPartsWithRegulars)
"strikethrough" -> StrikethroughTextSource(sourceSubstring, subPartsWithRegulars)
else -> RegularTextSource(sourceSubstring)
}
}
private inline operator fun <T : Comparable<T>> ClosedRange<T>.contains(other: ClosedRange<T>): Boolean {
return start <= other.start && endInclusive >= other.endInclusive
}
internal fun List<TextSource>.fillWithRegulars(source: String): List<TextSource> {
var index = 0
val result = mutableListOf<TextSource>()
for (i in 0 until size) {
val textSource = get(i)
val thisSourceInStart = source.startsWith(textSource.source, index)
if (!thisSourceInStart) {
val regularEndIndex = source.indexOf(textSource.source, index)
result.add(regular(source.substring(index, regularEndIndex)))
index = regularEndIndex
}
result.add(textSource)
index += textSource.source.length
}
if (index != source.length) {
result.add(regular(source.substring(index, source.length)))
}
return result
}
private fun createTextSources(originalFullString: String, entities: RawMessageEntities): List<TextSource> {
val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } }
val resultList = mutableListOf<TextSource>()
while (mutableEntities.isNotEmpty()) { while (mutableEntities.isNotEmpty()) {
val currentFirst = mutableEntities.removeAt(0) var parent = mutableEntities.removeFirst()
val subEntities = if (mutableEntities.isNotEmpty()) { val subentities = mutableListOf<RawMessageEntity>()
val lastIndex = currentFirst.offset + currentFirst.length val toAddCutted = mutableListOf<RawMessageEntity>()
val subEntities = mutableListOf<RawMessageEntity>() while (mutableEntities.isNotEmpty()) {
while (mutableEntities.isNotEmpty()) { val potentialParent = mutableEntities.first()
val currentPossibleSubEntity = mutableEntities.first() when {
if (currentPossibleSubEntity.offset < lastIndex) { potentialParent.range.first > parent.range.last -> break
subEntities.add(currentPossibleSubEntity) potentialParent.range in parent.range -> {
mutableEntities.removeAt(0) subentities.add(potentialParent)
} else { }
break potentialParent.offset == parent.offset && potentialParent.length > parent.length -> {
subentities.add(parent)
parent = potentialParent
}
else -> { // need to cut
toAddCutted.add(potentialParent)
} }
} }
subEntities mutableEntities.remove(potentialParent)
} else {
emptyList<RawMessageEntity>()
} }
val subtextSources = if (subentities.isNotEmpty()) {
resultList.addAll( mutableEntities.removeAll(subentities)
currentFirst.asTextParts( if (toAddCutted.isNotEmpty()) {
val borderIndex = parent.range.last + 1
mutableEntities.addAll(
0,
toAddCutted.map {
val firstLength = borderIndex - it.offset
subentities.add(it.copy(length = firstLength))
it.copy(
offset = borderIndex,
length = it.length - firstLength
)
}
)
}
createTextSources(originalFullString, subentities)
} else {
emptyList()
}
resultList.add(
parent.asTextSource(
originalFullString, originalFullString,
createTextPart(originalFullString, subEntities) subtextSources
) )
) )
} }
@@ -86,46 +130,41 @@ internal fun createTextPart(originalFullString: String, entities: RawMessageEnti
return resultList return resultList
} }
internal fun TextPart.asRawMessageEntities(): List<RawMessageEntity> { internal fun TextSource.toRawMessageEntities(offset: Int = 0): List<RawMessageEntity> {
val source = source val source = source
val length = range.last - range.first + 1 val length = source.length
return listOfNotNull( return listOfNotNull(
when (source) { when (this) {
is MentionTextSource -> RawMessageEntity("mention", range.first, length) is MentionTextSource -> RawMessageEntity("mention", offset, length)
is HashTagTextSource -> RawMessageEntity("hashtag", range.first, length) is HashTagTextSource -> RawMessageEntity("hashtag", offset, length)
is CashTagTextSource -> RawMessageEntity("cashtag", range.first, length) is CashTagTextSource -> RawMessageEntity("cashtag", offset, length)
is BotCommandTextSource -> RawMessageEntity("bot_command", range.first, length) is BotCommandTextSource -> RawMessageEntity("bot_command", offset, length)
is URLTextSource -> RawMessageEntity("url", range.first, length) is URLTextSource -> RawMessageEntity("url", offset, length)
is EMailTextSource -> RawMessageEntity("email", range.first, length) is EMailTextSource -> RawMessageEntity("email", offset, length)
is PhoneNumberTextSource -> RawMessageEntity("phone_number", range.first, length) is PhoneNumberTextSource -> RawMessageEntity("phone_number", offset, length)
is BoldTextSource -> RawMessageEntity("bold", range.first, length) is BoldTextSource -> RawMessageEntity("bold", offset, length)
is ItalicTextSource -> RawMessageEntity("italic", range.first, length) is ItalicTextSource -> RawMessageEntity("italic", offset, length)
is CodeTextSource -> RawMessageEntity("code", range.first, length) is CodeTextSource -> RawMessageEntity("code", offset, length)
is PreTextSource -> RawMessageEntity("pre", range.first, length, language = source.language) is PreTextSource -> RawMessageEntity("pre", offset, length, language = language)
is TextLinkTextSource -> RawMessageEntity("text_link", range.first, length, source.url) is TextLinkTextSource -> RawMessageEntity("text_link", offset, length, url)
is TextMentionTextSource -> RawMessageEntity("text_mention", range.first, length, user = source.user) is TextMentionTextSource -> RawMessageEntity("text_mention", offset, length, user = user)
is UnderlineTextSource -> RawMessageEntity("underline", range.first, length) is UnderlineTextSource -> RawMessageEntity("underline", offset, length)
is StrikethroughTextSource -> RawMessageEntity("strikethrough", range.first, length) is StrikethroughTextSource -> RawMessageEntity("strikethrough", offset, length)
else -> null else -> null
} }
) + if (source is MultilevelTextSource) { ) + if (this is MultilevelTextSource) {
source.textParts(range.first).asRawMessageEntities() subsources.toRawMessageEntities(offset)
} else { } else {
emptyList() emptyList()
} }
} }
internal fun List<TextPart>.asRawMessageEntities(): List<RawMessageEntity> = flatMap { it.asRawMessageEntities() }
internal fun List<TextSource>.toTextParts(preOffset: Int = 0): List<TextPart> { internal fun List<TextSource>.toRawMessageEntities(preOffset: Int = 0): List<RawMessageEntity> {
var i = preOffset var i = preOffset
return map { return flatMap { textSource ->
TextPart( textSource.toRawMessageEntities(i).also {
i until (i + it.source.length), i += it.maxByOrNull { it.length } ?.length ?: textSource.source.length
it
).also {
i = it.range.last + 1
} }
} }
} }
@@ -136,10 +175,8 @@ fun String.removeLeading(word: String) = if (startsWith(word)){
this this
} }
internal fun List<TextSource>.toRawMessageEntities(): List<RawMessageEntity> = toTextParts().asRawMessageEntities() internal fun List<TextSource>.toRawMessageEntities(): List<RawMessageEntity> = toRawMessageEntities(0)
internal fun RawMessageEntities.asTextParts(sourceString: String): List<TextPart> = sourceString.fullListOfSubSource( internal fun RawMessageEntities.asTextSources(sourceString: String): List<TextSource> = createTextSources(sourceString, this).fillWithRegulars(sourceString)
createTextPart(sourceString, this)
)
internal typealias RawMessageEntities = List<RawMessageEntity> internal typealias RawMessageEntities = List<RawMessageEntity>

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see bold * @see bold
*/ */
@Serializable
data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -4,12 +4,14 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
private val commandRegex = Regex("[/!][^@\\s]*") private val commandRegex = Regex("[/!][^@\\s]*")
/** /**
* @see botCommand * @see botCommand
*/ */
@Serializable
data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String override val source: String
) : TextSource { ) : TextSource {

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see cashTag * @see cashTag
*/ */
@Serializable
data class CashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class CashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see code * @see code
*/ */
@Serializable
data class CodeTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class CodeTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String override val source: String
) : TextSource { ) : TextSource {

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see email * @see email
*/ */
@Serializable
data class EMailTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class EMailTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see hashtag * @see hashtag
*/ */
@Serializable
data class HashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class HashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see italic * @see italic
*/ */
@Serializable
data class ItalicTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class ItalicTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
private val String.withoutCommercialAt private val String.withoutCommercialAt
get() = if (startsWith("@")) { get() = if (startsWith("@")) {
@@ -14,6 +15,7 @@ private val String.withoutCommercialAt
/** /**
* @see mention * @see mention
*/ */
@Serializable
data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see phone * @see phone
*/ */
@Serializable
data class PhoneNumberTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class PhoneNumberTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see pre * @see pre
*/ */
@Serializable
data class PreTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class PreTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
val language: String? = null val language: String? = null

View File

@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see regular * @see regular
*/ */
@Serializable
data class RegularTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class RegularTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String override val source: String
) : TextSource { ) : TextSource {

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see strikethrough * @see strikethrough
*/ */
@Serializable
data class StrikethroughTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class StrikethroughTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see link * @see link
*/ */
@Serializable
data class TextLinkTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class TextLinkTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
val url: String val url: String

View File

@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see mention * @see mention
*/ */
@Serializable
data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
val user: User, val user: User,

View File

@@ -0,0 +1,42 @@
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.types.MessageEntity.RawMessageEntity
import dev.inmo.tgbotapi.types.MessageEntity.asTextSources
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
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)
}
}

View File

@@ -4,10 +4,12 @@ import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see link * @see link
*/ */
@Serializable
data class URLTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class URLTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String override val source: String
) : TextSource { ) : TextSource {

View File

@@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.* import dev.inmo.tgbotapi.utils.internal.*
import kotlinx.serialization.Serializable
/** /**
* @see underline * @see underline
*/ */
@Serializable
data class UnderlineTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( data class UnderlineTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String, override val source: String,
override val subsources: List<TextSource> override val subsources: List<TextSource>

View File

@@ -26,6 +26,8 @@ internal object BotActionSerializer: KSerializer<BotAction> {
UploadVideoAction.actionName -> UploadVideoAction UploadVideoAction.actionName -> UploadVideoAction
RecordAudioAction.actionName -> RecordAudioAction RecordAudioAction.actionName -> RecordAudioAction
UploadAudioAction.actionName -> UploadAudioAction UploadAudioAction.actionName -> UploadAudioAction
RecordVoiceAction.actionName -> RecordVoiceAction
UploadVoiceAction.actionName -> UploadVoiceAction
UploadDocumentAction.actionName -> UploadDocumentAction UploadDocumentAction.actionName -> UploadDocumentAction
FindLocationAction.actionName -> FindLocationAction FindLocationAction.actionName -> FindLocationAction
RecordVideoNoteAction.actionName -> RecordVideoNoteAction RecordVideoNoteAction.actionName -> RecordVideoNoteAction
@@ -83,24 +85,70 @@ inline fun BotAction.asUploadVideo() = this as? UploadVideoAction
* Will notify user that bot is recording some audio * Will notify user that bot is recording some audio
*/ */
@Serializable(BotActionSerializer::class) @Serializable(BotActionSerializer::class)
@Deprecated(
"Deprecated according to https://core.telegram.org/bots/api-changelog#april-26-2021",
ReplaceWith("RecordVoiceAction", "dev.inmo.tgbotapi.types.actions.RecordVoiceAction")
)
object RecordAudioAction : BotAction() { object RecordAudioAction : BotAction() {
override val actionName: String = "record_audio" override val actionName: String = "record_audio"
} }
@Deprecated(
"Deprecated according to https://core.telegram.org/bots/api-changelog#april-26-2021",
ReplaceWith("recordVoice", "dev.inmo.tgbotapi.types.actions.recordVoice")
)
inline val recordAudio inline val recordAudio
get() = RecordAudioAction get() = RecordAudioAction
@Deprecated(
"Deprecated according to https://core.telegram.org/bots/api-changelog#april-26-2021",
ReplaceWith("asRecordVoice", "dev.inmo.tgbotapi.types.actions.asRecordVoice")
)
inline fun BotAction.asRecordAudio() = this as? RecordAudioAction inline fun BotAction.asRecordAudio() = this as? RecordAudioAction
/** /**
* Will notify user that bot is uploading some audio * Will notify user that bot is uploading some audio
*/ */
@Serializable(BotActionSerializer::class) @Serializable(BotActionSerializer::class)
@Deprecated(
"Deprecated according to https://core.telegram.org/bots/api-changelog#april-26-2021",
ReplaceWith("UploadVoiceAction", "dev.inmo.tgbotapi.types.actions.UploadVoiceAction")
)
object UploadAudioAction : BotAction() { object UploadAudioAction : BotAction() {
override val actionName: String = "upload_audio" override val actionName: String = "upload_audio"
} }
@Deprecated(
"Deprecated according to https://core.telegram.org/bots/api-changelog#april-26-2021",
ReplaceWith("uploadVoice", "dev.inmo.tgbotapi.types.actions.uploadVoice")
)
inline val uploadAudio inline val uploadAudio
get() = UploadAudioAction get() = UploadAudioAction
@Deprecated(
"Deprecated according to https://core.telegram.org/bots/api-changelog#april-26-2021",
ReplaceWith("asUploadVoice", "dev.inmo.tgbotapi.types.actions.asUploadVoice")
)
inline fun BotAction.asUploadAudio() = this as? UploadAudioAction inline fun BotAction.asUploadAudio() = this as? UploadAudioAction
/**
* Will notify user that bot is recording some audio
*/
@Serializable(BotActionSerializer::class)
object RecordVoiceAction : BotAction() {
override val actionName: String = "record_voice"
}
inline val recordVoice
get() = RecordVoiceAction
inline fun BotAction.asRecordVoice() = this as? RecordVoiceAction
/**
* Will notify user that bot is uploading some audio
*/
@Serializable(BotActionSerializer::class)
object UploadVoiceAction : BotAction() {
override val actionName: String = "upload_voice"
}
inline val uploadVoice
get() = UploadVoiceAction
inline fun BotAction.asUploadVoice() = this as? UploadVoiceAction
/** /**
* Will notify user that bot is uploading some document * Will notify user that bot is uploading some document
*/ */

View File

@@ -21,7 +21,7 @@ data class InlineKeyboardMarkup(
// first button is not PayInlineKeyboardButton // first button is not PayInlineKeyboardButton
val firstIsPaymentButton = keyboard.first().firstOrNull() is PayInlineKeyboardButton val firstIsPaymentButton = keyboard.first().firstOrNull() is PayInlineKeyboardButton
if (!firstIsPaymentButton) { if (!firstIsPaymentButton) {
error("In case if PayInlineKeyboardButton included in keyboard - it must ") error("In case if PayInlineKeyboardButton included in keyboard - it must be the first one")
} }
} }
} }

View File

@@ -4,10 +4,10 @@ import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.chat.abstracts.UnknownChatType import dev.inmo.tgbotapi.types.chat.abstracts.UnknownChatType
import dev.inmo.tgbotapi.types.chat.abstracts.extended.ExtendedChat import dev.inmo.tgbotapi.types.chat.abstracts.extended.ExtendedChat
import dev.inmo.tgbotapi.types.chat.abstracts.extended.UnknownExtendedChat
import dev.inmo.tgbotapi.types.chat.extended.* import dev.inmo.tgbotapi.types.chat.extended.*
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.* import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
@@ -17,6 +17,40 @@ import kotlinx.serialization.json.*
private val formatter private val formatter
get() = nonstrictJsonFormat get() = nonstrictJsonFormat
@Serializable(ChatTypeSerializer::class)
sealed class ChatType {
abstract val stringified: String
@Serializable(ChatTypeSerializer::class)
object PrivateChatType : ChatType() { override val stringified = "private" }
@Serializable(ChatTypeSerializer::class)
object GroupChatType : ChatType() { override val stringified = "group" }
@Serializable(ChatTypeSerializer::class)
object SupergroupChatType : ChatType() { override val stringified = "supergroup" }
@Serializable(ChatTypeSerializer::class)
object ChannelChatType : ChatType() { override val stringified = "channel" }
@Serializable(ChatTypeSerializer::class)
class UnknownChatType(override val stringified: String) : ChatType()
}
val String.asChatType
get() = when (this) {
ChatType.PrivateChatType.stringified -> ChatType.PrivateChatType
ChatType.GroupChatType.stringified -> ChatType.GroupChatType
ChatType.SupergroupChatType.stringified -> ChatType.SupergroupChatType
ChatType.ChannelChatType.stringified -> ChatType.ChannelChatType
else -> ChatType.UnknownChatType(this)
}
@Serializer(ChatType::class)
object ChatTypeSerializer : KSerializer<ChatType> {
override val descriptor: SerialDescriptor = String.serializer().descriptor
override fun deserialize(decoder: Decoder): ChatType {
return decoder.decodeString().asChatType
}
override fun serialize(encoder: Encoder, value: ChatType) {
encoder.encodeString(value.stringified)
}
}
internal object PreviewChatSerializer : KSerializer<Chat> { internal object PreviewChatSerializer : KSerializer<Chat> {
@InternalSerializationApi @InternalSerializationApi
override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN) override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN)
@@ -24,14 +58,14 @@ internal object PreviewChatSerializer : KSerializer<Chat> {
override fun deserialize(decoder: Decoder): Chat { override fun deserialize(decoder: Decoder): Chat {
val decodedJson = JsonObject.serializer().deserialize(decoder) val decodedJson = JsonObject.serializer().deserialize(decoder)
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?: error("Field $typeField must be presented, but absent in $decodedJson") val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
return when (type) { return when (type) {
"private" -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson) ChatType.PrivateChatType -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson)
"group" -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson) ChatType.GroupChatType -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson)
"supergroup" -> formatter.decodeFromJsonElement(SupergroupChatImpl.serializer(), decodedJson) ChatType.SupergroupChatType -> formatter.decodeFromJsonElement(SupergroupChatImpl.serializer(), decodedJson)
"channel" -> formatter.decodeFromJsonElement(ChannelChatImpl.serializer(), decodedJson) ChatType.ChannelChatType -> formatter.decodeFromJsonElement(ChannelChatImpl.serializer(), decodedJson)
else -> UnknownChatType( is ChatType.UnknownChatType -> UnknownChatType(
formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(), formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(),
decodedJson.toString() decodedJson.toString()
) )
@@ -56,14 +90,18 @@ internal object ExtendedChatSerializer : KSerializer<ExtendedChat> {
override fun deserialize(decoder: Decoder): ExtendedChat { override fun deserialize(decoder: Decoder): ExtendedChat {
val decodedJson = JsonObject.serializer().deserialize(decoder) val decodedJson = JsonObject.serializer().deserialize(decoder)
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?: error("Field $typeField must be presented, but absent in $decodedJson") val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
return when (type) { return when (type) {
"private" -> formatter.decodeFromJsonElement(ExtendedPrivateChatImpl.serializer(), decodedJson) // else -> throw IllegalArgumentException("Unknown type of chat")
"group" -> formatter.decodeFromJsonElement(ExtendedGroupChatImpl.serializer(), decodedJson) ChatType.PrivateChatType -> formatter.decodeFromJsonElement(ExtendedPrivateChatImpl.serializer(), decodedJson)
"supergroup" -> formatter.decodeFromJsonElement(ExtendedSupergroupChatImpl.serializer(), decodedJson) ChatType.GroupChatType -> formatter.decodeFromJsonElement(ExtendedGroupChatImpl.serializer(), decodedJson)
"channel" -> formatter.decodeFromJsonElement(ExtendedChannelChatImpl.serializer(), decodedJson) ChatType.SupergroupChatType -> formatter.decodeFromJsonElement(ExtendedSupergroupChatImpl.serializer(), decodedJson)
else -> throw IllegalArgumentException("Unknown type of chat") ChatType.ChannelChatType -> formatter.decodeFromJsonElement(ExtendedChannelChatImpl.serializer(), decodedJson)
is ChatType.UnknownChatType -> UnknownExtendedChat(
formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(),
decodedJson.toString()
)
} }
} }

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types.chat.abstracts.extended package dev.inmo.tgbotapi.types.chat.abstracts.extended
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.ChatPhoto import dev.inmo.tgbotapi.types.ChatPhoto
import dev.inmo.tgbotapi.types.chat.ExtendedChatSerializer import dev.inmo.tgbotapi.types.chat.ExtendedChatSerializer
import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.chat.abstracts.Chat
@@ -8,4 +9,11 @@ import kotlinx.serialization.Serializable
@Serializable(ExtendedChatSerializer::class) @Serializable(ExtendedChatSerializer::class)
interface ExtendedChat : Chat { interface ExtendedChat : Chat {
val chatPhoto: ChatPhoto? val chatPhoto: ChatPhoto?
} }
data class UnknownExtendedChat(
override val id: ChatId,
val raw: String
) : ExtendedChat {
override val chatPhoto: ChatPhoto? = null
}

View File

@@ -34,11 +34,11 @@ data class VideoFile(
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
inline fun VideoFile.toInputMediaVideo( inline fun VideoFile.toInputMediaVideo(
caption: String? = null, text: String? = null,
parseMode: ParseMode? = null parseMode: ParseMode? = null
) = InputMediaVideo( ) = InputMediaVideo(
fileId, fileId,
caption, text,
parseMode, parseMode,
width, width,
height, height,

View File

@@ -8,7 +8,7 @@ data class Game(
override val title: String, override val title: String,
val description: String, val description: String,
val photo: Photo, val photo: Photo,
override val caption: String? = null, override val text: String? = null,
override val captionEntities: List<TextPart> = emptyList(), override val textSources: TextSourcesList = emptyList(),
val animation: AnimationFile? = null val animation: AnimationFile? = null
) : Titled, CaptionedInput ) : Titled, CaptionedInput, TextedInput

View File

@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.games
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities
import dev.inmo.tgbotapi.types.MessageEntity.asTextParts import dev.inmo.tgbotapi.types.MessageEntity.asTextSources
import dev.inmo.tgbotapi.types.files.* import dev.inmo.tgbotapi.types.files.*
import kotlinx.serialization.* import kotlinx.serialization.*
@@ -16,9 +16,9 @@ internal data class RawGame(
@SerialName(photoField) @SerialName(photoField)
private val photo: Photo, private val photo: Photo,
@SerialName(textField) @SerialName(textField)
private val caption: String? = null, private val text: String? = null,
@SerialName(textEntitiesField) @SerialName(textEntitiesField)
private val captionEntities: RawMessageEntities = emptyList(), private val textEntities: RawMessageEntities = emptyList(),
@SerialName(animationField) @SerialName(animationField)
private val animation: AnimationFile? = null private val animation: AnimationFile? = null
) { ) {
@@ -27,8 +27,8 @@ internal data class RawGame(
title, title,
description, description,
photo, photo,
caption, text,
caption ?.let { _ -> captionEntities.asTextParts(caption) } ?: emptyList(), text ?.let { _ -> textEntities.asTextSources(text) } ?: emptyList(),
animation animation
) )
} }

View File

@@ -1,3 +1,3 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts
interface VoiceChatEvent : SupergroupEvent interface VoiceChatEvent : CommonEvent

View File

@@ -0,0 +1,13 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import dev.inmo.tgbotapi.types.startDateField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class VoiceChatScheduled(
@SerialName(startDateField)
val startDate: TelegramDate
) : VoiceChatEvent

View File

@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.message
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities
import dev.inmo.tgbotapi.types.MessageEntity.asTextParts import dev.inmo.tgbotapi.types.MessageEntity.asTextSources
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup 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
@@ -83,6 +83,7 @@ internal data class RawMessage(
private val successful_payment: SuccessfulPayment? = null, private val successful_payment: SuccessfulPayment? = null,
// Voice Chat Service Messages // Voice Chat Service Messages
private val voice_chat_scheduled: VoiceChatScheduled? = null,
private val voice_chat_started: VoiceChatStarted? = null, private val voice_chat_started: VoiceChatStarted? = null,
private val voice_chat_ended: VoiceChatEnded? = null, private val voice_chat_ended: VoiceChatEnded? = null,
private val voice_chat_participants_invited: VoiceChatParticipantsInvited? = null, private val voice_chat_participants_invited: VoiceChatParticipantsInvited? = null,
@@ -101,11 +102,11 @@ internal data class RawMessage(
) { ) {
private val content: MessageContent? by lazy { private val content: MessageContent? by lazy {
val adaptedCaptionEntities = caption ?.let { val adaptedCaptionEntities = caption ?.let {
(caption_entities ?: emptyList()).asTextParts(caption) (caption_entities ?: emptyList()).asTextSources(caption)
} ?: emptyList() } ?: emptyList()
when { when {
text != null -> TextContent(text, (entities ?: emptyList()).asTextParts(text)) text != null -> TextContent(text, (entities ?: emptyList()).asTextSources(text))
audio != null -> AudioContent( audio != null -> AudioContent(
audio, audio,
caption, caption,
@@ -182,6 +183,7 @@ internal data class RawMessage(
new_chat_title != null -> NewChatTitle(new_chat_title) new_chat_title != null -> NewChatTitle(new_chat_title)
new_chat_photo != null -> NewChatPhoto(new_chat_photo.toList()) new_chat_photo != null -> NewChatPhoto(new_chat_photo.toList())
voice_chat_started != null -> voice_chat_started voice_chat_started != null -> voice_chat_started
voice_chat_scheduled != null -> voice_chat_scheduled
message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed
voice_chat_ended != null -> voice_chat_ended voice_chat_ended != null -> voice_chat_ended
voice_chat_participants_invited != null -> voice_chat_participants_invited voice_chat_participants_invited != null -> voice_chat_participants_invited

View File

@@ -1,7 +1,5 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.CommonAbstracts.FromUser
interface FromUserMessage { interface FromUserMessage : FromUser, Message
val user: User
}

View File

@@ -1,19 +1,18 @@
package dev.inmo.tgbotapi.types.message.content package dev.inmo.tgbotapi.types.message.content
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.SendTextMessage import dev.inmo.tgbotapi.requests.send.SendTextMessage
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.defaultParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
data class TextContent( data class TextContent(
override val text: String, override val text: String,
override val textEntities: List<TextPart> = emptyList() override val textSources: TextSourcesList = emptyList(),
) : MessageContent, TextedInput { ) : MessageContent, TextedInput {
override fun createResend( override fun createResend(
chatId: ChatIdentifier, chatId: ChatIdentifier,

View File

@@ -1,9 +1,10 @@
package dev.inmo.tgbotapi.types.message.content.abstracts package dev.inmo.tgbotapi.types.message.content.abstracts
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
import dev.inmo.tgbotapi.types.InputMedia.* import dev.inmo.tgbotapi.types.InputMedia.*
interface MediaGroupContent : MediaContent, CaptionedInput { interface MediaGroupContent : MediaContent, CaptionedInput, TextedInput {
fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
} }

View File

@@ -15,9 +15,9 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
data class AnimationContent( data class AnimationContent(
override val media: AnimationFile, override val media: AnimationFile,
val includedDocument: DocumentFile?, val includedDocument: DocumentFile?,
override val caption: String?, override val text: String?,
override val captionEntities: List<TextPart> override val textSources: TextSourcesList = emptyList()
) : MediaContent, CaptionedInput { ) : MediaContent, CaptionedInput, TextedInput {
override fun createResend( override fun createResend(
chatId: ChatIdentifier, chatId: ChatIdentifier,
disableNotification: Boolean, disableNotification: Boolean,

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.message.content.media package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.TextPart import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendAudio import dev.inmo.tgbotapi.requests.send.media.SendAudio
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
@@ -15,8 +14,8 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.AudioMediaGroupContent
data class AudioContent( data class AudioContent(
override val media: AudioFile, override val media: AudioFile,
override val caption: String? = null, override val text: String? = null,
override val captionEntities: List<TextPart> = emptyList() override val textSources: TextSourcesList = emptyList()
) : AudioMediaGroupContent { ) : AudioMediaGroupContent {
override fun createResend( override fun createResend(
chatId: ChatIdentifier, chatId: ChatIdentifier,

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.message.content.media package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendDocument import dev.inmo.tgbotapi.requests.send.media.SendDocument
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
@@ -16,8 +17,8 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
data class DocumentContent( data class DocumentContent(
override val media: DocumentFile, override val media: DocumentFile,
override val caption: String? = null, override val text: String? = null,
override val captionEntities: List<TextPart> = emptyList() override val textSources: TextSourcesList = emptyList()
) : DocumentMediaGroupContent { ) : DocumentMediaGroupContent {
override fun createResend( override fun createResend(
chatId: ChatIdentifier, chatId: ChatIdentifier,
@@ -43,10 +44,10 @@ data class DocumentContent(
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
inline fun MediaContent.asDocumentContent() = when (this) { inline fun MediaContent.asDocumentContent() = when (this) {
is CaptionedInput -> DocumentContent( is TextedInput -> DocumentContent(
media.asDocumentFile(), media.asDocumentFile(),
caption, text,
captionEntities textSources
) )
else -> DocumentContent( else -> DocumentContent(
media.asDocumentFile() media.asDocumentFile()

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.message.content.media package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.TextPart import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendPhoto import dev.inmo.tgbotapi.requests.send.media.SendPhoto
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
@@ -16,8 +15,8 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
data class PhotoContent( data class PhotoContent(
override val mediaCollection: Photo, override val mediaCollection: Photo,
override val caption: String? = null, override val text: String? = null,
override val captionEntities: List<TextPart> = emptyList() override val textSources: TextSourcesList = emptyList()
) : MediaCollectionContent<PhotoSize>, VisualMediaGroupContent { ) : MediaCollectionContent<PhotoSize>, VisualMediaGroupContent {
override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content") override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content")

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.message.content.media package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.TextPart import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendVideo import dev.inmo.tgbotapi.requests.send.media.SendVideo
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
@@ -15,8 +14,8 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
data class VideoContent( data class VideoContent(
override val media: VideoFile, override val media: VideoFile,
override val caption: String? = null, override val text: String? = null,
override val captionEntities: List<TextPart> = emptyList() override val textSources: TextSourcesList = emptyList()
) : VisualMediaGroupContent { ) : VisualMediaGroupContent {
override fun createResend( override fun createResend(
chatId: ChatIdentifier, chatId: ChatIdentifier,

View File

@@ -13,9 +13,9 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
data class VoiceContent( data class VoiceContent(
override val media: VoiceFile, override val media: VoiceFile,
override val caption: String? = null, override val text: String? = null,
override val captionEntities: List<TextPart> = emptyList() override val textSources: TextSourcesList = emptyList()
) : MediaContent, CaptionedInput { ) : MediaContent, CaptionedInput, TextedInput {
override fun createResend( override fun createResend(
chatId: ChatIdentifier, chatId: ChatIdentifier,
disableNotification: Boolean, disableNotification: Boolean,

View File

@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.types.polls
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan import com.soywiz.klock.TimeSpan
import dev.inmo.tgbotapi.CommonAbstracts.ExplainedInput import dev.inmo.tgbotapi.CommonAbstracts.ExplainedInput
import dev.inmo.tgbotapi.CommonAbstracts.TextPart import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.* import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
@@ -135,8 +135,8 @@ data class QuizPoll(
* Nullable due to documentation (https://core.telegram.org/bots/api#poll) * Nullable due to documentation (https://core.telegram.org/bots/api#poll)
*/ */
val correctOptionId: Int? = null, val correctOptionId: Int? = null,
override val explanation: String? = null, override val text: String? = null,
override val explanationEntities: List<TextPart> = emptyList(), override val textSources: List<TextSource> = emptyList(),
override val isClosed: Boolean = false, override val isClosed: Boolean = false,
override val isAnonymous: Boolean = false, override val isAnonymous: Boolean = false,
override val scheduledCloseInfo: ScheduledCloseInfo? = null override val scheduledCloseInfo: ScheduledCloseInfo? = null
@@ -159,7 +159,7 @@ internal object PollSerializer : KSerializer<Poll> {
rawPoll.votesCount, rawPoll.votesCount,
rawPoll.correctOptionId, rawPoll.correctOptionId,
rawPoll.explanation, rawPoll.explanation,
rawPoll.explanation?.let { rawPoll.explanationEntities.asTextParts(it) } ?: emptyList(), rawPoll.explanation?.let { rawPoll.explanationEntities.asTextSources(it) } ?: emptyList(),
rawPoll.isClosed, rawPoll.isClosed,
rawPoll.isAnonymous, rawPoll.isAnonymous,
rawPoll.scheduledCloseInfo rawPoll.scheduledCloseInfo
@@ -210,8 +210,8 @@ internal object PollSerializer : KSerializer<Poll> {
value.isAnonymous, value.isAnonymous,
regularPollType, regularPollType,
correctOptionId = value.correctOptionId, correctOptionId = value.correctOptionId,
explanation = value.explanation, explanation = value.text,
explanationEntities = value.explanationEntities.asRawMessageEntities(), explanationEntities = value.textSources.toRawMessageEntities(),
openPeriod = (closeInfo as? ApproximateScheduledCloseInfo) ?.openDuration ?.seconds ?.toLong(), openPeriod = (closeInfo as? ApproximateScheduledCloseInfo) ?.openDuration ?.seconds ?.toLong(),
closeDate = (closeInfo as? ExactScheduledCloseInfo) ?.closeDateTime ?.unixMillisLong ?.div(1000L) closeDate = (closeInfo as? ExactScheduledCloseInfo) ?.closeDateTime ?.unixMillisLong ?.div(1000L)
) )

View File

@@ -1,77 +1,12 @@
package dev.inmo.tgbotapi.utils.internal package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.CommonAbstracts.MultilevelTextSource
import dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.types.UserId import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.link import dev.inmo.tgbotapi.types.link
import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Link import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Link
import dev.inmo.tgbotapi.utils.extensions.toHtml import dev.inmo.tgbotapi.utils.extensions.toHtml
internal fun String.fullListOfSubSource(sourceList: List<TextPart>): List<TextPart> {
val sortedSourceList = sourceList.sortedBy { it.range.first }.toMutableList()
var previousLastIndex = 0
val newSubSources = mutableListOf<TextPart>()
while (sortedSourceList.isNotEmpty()) {
val topSource = sortedSourceList.removeAt(0)
if (topSource.range.first - previousLastIndex > 0) {
val range = previousLastIndex until topSource.range.first
newSubSources.add(
TextPart(
range,
RegularTextSource(
substring(range)
)
)
)
}
newSubSources.add(topSource)
previousLastIndex = topSource.range.last + 1
}
if (length > previousLastIndex) {
val range = previousLastIndex until length
newSubSources.add(
TextPart(
range,
RegularTextSource(
substring(range)
)
)
)
}
return newSubSources
}
internal fun List<TextPart>.shiftSourcesToTheLeft(shiftCount: Int = 1): List<TextPart> {
return mapNotNull {
val first = (it.range.first - shiftCount).let { firstCalculated ->
if (firstCalculated < 0) {
0
} else {
firstCalculated
}
}
val last = (it.range.last - shiftCount).let { lastCalculated ->
if (lastCalculated < 0) {
0
} else {
lastCalculated
}
}
it.copy(range = first .. last).let { newSubSource ->
if (newSubSource.range.isEmpty()) {
null
} else {
newSubSource
}
}
}
}
private fun List<TextSource>.joinSubSourcesMarkdownV2() = joinToString("") { private fun List<TextSource>.joinSubSourcesMarkdownV2() = joinToString("") {
it.markdownV2 it.markdownV2
} }

View File

@@ -22,6 +22,8 @@ class BotActionTests {
UploadVideoAction -> example.botAction.actionName UploadVideoAction -> example.botAction.actionName
RecordAudioAction -> example.botAction.actionName RecordAudioAction -> example.botAction.actionName
UploadAudioAction -> example.botAction.actionName UploadAudioAction -> example.botAction.actionName
RecordVoiceAction -> example.botAction.actionName
UploadVoiceAction -> example.botAction.actionName
UploadDocumentAction -> example.botAction.actionName UploadDocumentAction -> example.botAction.actionName
FindLocationAction -> example.botAction.actionName FindLocationAction -> example.botAction.actionName
RecordVideoNoteAction -> example.botAction.actionName RecordVideoNoteAction -> example.botAction.actionName
@@ -51,6 +53,8 @@ class BotActionTests {
UploadVideoAction.example(), UploadVideoAction.example(),
RecordAudioAction.example(), RecordAudioAction.example(),
UploadAudioAction.example(), UploadAudioAction.example(),
RecordVoiceAction.example(),
UploadVoiceAction.example(),
UploadDocumentAction.example(), UploadDocumentAction.example(),
FindLocationAction.example(), FindLocationAction.example(),
RecordVideoNoteAction.example(), RecordVideoNoteAction.example(),

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.MessageEntity package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.TextPart import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.types.MessageEntity.textsources.* import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import kotlin.test.assertTrue import kotlin.test.assertTrue
@@ -36,19 +36,19 @@ internal val testTextEntities = listOf(
RawMessageEntity( RawMessageEntity(
"mention", "mention",
39, 39,
6 8
) )
) )
fun List<TextPart>.testTextParts() { fun List<TextSource>.testTextSources() {
assertTrue (first().source is RegularTextSource) assertTrue (first() is RegularTextSource)
assertTrue (get(1).source is BoldTextSource) assertTrue (get(1) is BoldTextSource)
assertTrue (get(2).source is RegularTextSource) assertTrue (get(2) is RegularTextSource)
assertTrue (get(3).source is HashTagTextSource) assertTrue (get(3) is HashTagTextSource)
assertTrue (get(4).source is RegularTextSource) assertTrue (get(4) is RegularTextSource)
assertTrue (get(5).source is MentionTextSource) assertTrue (get(5) is MentionTextSource)
val boldSource = get(1).source as BoldTextSource val boldSource = get(1) as BoldTextSource
assertTrue (boldSource.subsources.first() is ItalicTextSource) assertTrue (boldSource.subsources.first() is ItalicTextSource)
assertTrue (boldSource.subsources[1] is RegularTextSource) assertTrue (boldSource.subsources[1] is RegularTextSource)
assertTrue (boldSource.subsources[2] is StrikethroughTextSource) assertTrue (boldSource.subsources[2] is StrikethroughTextSource)

View File

@@ -48,7 +48,7 @@ class StringFormattingTests {
hashtag("tag") + hashtag("tag") +
" and " + " and " +
mention("mention") mention("mention")
sources.toTextParts().testTextParts() sources.testTextSources()
assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first()) assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first())
assertEquals(formattedHtmlText, sources.toHtmlTexts().first()) assertEquals(formattedHtmlText, sources.toHtmlTexts().first())

View File

@@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.types.MessageEntity package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.justTextSources
import dev.inmo.tgbotapi.extensions.utils.formatting.toHtmlTexts import dev.inmo.tgbotapi.extensions.utils.formatting.toHtmlTexts
import dev.inmo.tgbotapi.extensions.utils.formatting.toMarkdownV2Texts import dev.inmo.tgbotapi.extensions.utils.formatting.toMarkdownV2Texts
import kotlin.test.Test import kotlin.test.Test
@@ -9,23 +8,23 @@ import kotlin.test.assertEquals
class TextPartsCreatingTests { class TextPartsCreatingTests {
@Test @Test
fun testThatTextWithMultilevelPartsCorrectlyCreating() { fun testThatTextWithMultilevelPartsCorrectlyCreating() {
val textParts = testTextEntities.asTextParts(testText) val textSources = testTextEntities.asTextSources(testText)
textParts.testTextParts() textSources.testTextSources()
assertEquals( assertEquals(
formattedV2Text, formattedV2Text,
textParts.justTextSources().toMarkdownV2Texts().first() textSources.toMarkdownV2Texts().first()
) )
} }
@Test @Test
fun testThatTextWithMultilevelPartsCorrectlyCreatingInHtml() { fun testThatTextWithMultilevelPartsCorrectlyCreatingInHtml() {
val textParts = testTextEntities.asTextParts(testText) val textSources = testTextEntities.asTextSources(testText)
textParts.testTextParts() textSources.testTextSources()
assertEquals( assertEquals(
formattedHtmlText, formattedHtmlText,
textParts.justTextSources().toHtmlTexts().first() textSources.toHtmlTexts().first()
) )
} }
} }

View File

@@ -0,0 +1,37 @@
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 kotlinx.serialization.builtins.ListSerializer
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())
}
}

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.extensions.api.edit.caption package dev.inmo.tgbotapi.extensions.api.edit.caption
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.edit.caption.EditChatMessageCaption import dev.inmo.tgbotapi.requests.edit.caption.EditChatMessageCaption
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
@@ -35,7 +34,7 @@ suspend fun <T> TelegramBot.editMessageCaption(
text: String, text: String,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<MediaContent> where T : CaptionedInput, T : MediaContent { ): ContentMessage<MediaContent> where T : TextedWithTextSources, T : MediaContent {
return editMessageCaption(message.chat.id, message.messageId, text, parseMode, replyMarkup) return editMessageCaption(message.chat.id, message.messageId, text, parseMode, replyMarkup)
} }
@@ -59,6 +58,6 @@ suspend fun <T> TelegramBot.editMessageCaption(
message: ContentMessage<T>, message: ContentMessage<T>,
entities: List<TextSource>, entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<MediaContent> where T : CaptionedInput, T : MediaContent { ): ContentMessage<MediaContent> where T : TextedWithTextSources, T : MediaContent {
return editMessageCaption(message.chat.id, message.messageId, entities, replyMarkup) return editMessageCaption(message.chat.id, message.messageId, entities, replyMarkup)
} }

View File

@@ -2,7 +2,8 @@ package dev.inmo.tgbotapi.extensions.api.passport
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.SetPassportDataErrors import dev.inmo.tgbotapi.requests.SetPassportDataErrors
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.message.PassportMessage import dev.inmo.tgbotapi.types.message.PassportMessage
import dev.inmo.tgbotapi.types.passport.PassportData import dev.inmo.tgbotapi.types.passport.PassportData
import dev.inmo.tgbotapi.types.passport.PassportElementError import dev.inmo.tgbotapi.types.passport.PassportElementError

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