1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-26 03:58:44 +00:00

Merge pull request #163 from InsanusMokrassar/0.30.0

0.30.0
This commit is contained in:
InsanusMokrassar 2020-11-07 23:00:35 +06:00 committed by GitHub
commit 6caa7dd428
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
234 changed files with 4889 additions and 979 deletions

View File

@ -1,5 +1,93 @@
# TelegramBotAPI changelog
## 0.30.0 Bot API 5.0
**THIS UPDATE CONTAINS A LOT OF BREAKING CHANGES. PLEASE, BE CAREFUL ON UPGRADING OF YOUR PROJECT**
* `Common`:
* `Version`:
* `Coroutine`: `1.4.0` -> `1.4.1`
* **NEW** `MicroUtils`: `0.2.7`
* `Core`:
* Support of `logOut` method (`LogOut` object as a `Request`)
* Support of `close` method (`Close` object as a `Request`)
* `SetWebhook` updates:
* New field `ipAddress`. It works the same as `ip_address` in [setWebhook](https://core.telegram.org/bots/api#setwebhook)
section
* New field `dropPendingUpdates`. It works the same as `drop_pending_updates` in [setWebhook](https://core.telegram.org/bots/api#setwebhook)
section
* New field `ExtendedPrivateChat#bio`
* New data class `ChatLocation`
* New field `UnbanChatMember#onlyIfBanned`
* New fields `ExtendedChannelChat#linkedGroupChatId` and `ExtendedSupergroupChat#linkedChannelChatId`
* New fields `ExtendedSupergroupChat#location`
* New fields `AudioFile#fileName` and `VideoFile#fileName`
* New fields `SendDocument#disableContentTypeDetection` and `InputMediaDocument#disableContentTypeDetection`
* New request `UnpinAllChatMessages`
* New parameter for `unpinChatMessage` method: `messageId`
* New dice type `FootballDiceAnimationType`
* Limits for dices has been changed
* `commonDiceResultLimit` has been deprecated
* New field `DiceAnimationType#valueLimits`
* Locations updates:
* New interface `Headed` with property `heading`
* New interface `HorizontallyAccured` with property `horizontalAccuracy`
* New interface `ProximityAlertable` with property `proximityAlertRadius`
* `Location` class has been separated:
* `StaticLocation` for static locations
* `LiveLocation` for live locations
* Property `Livable#livePeriod` now use typealias type `Seconds` (the same by meaning - `Int`)
* `EditLocationMessage` now extends `Locationed`, `HorizontallyAccured`, `ProximityAlertable` and `Headed` interfaces
* New properties in `EditChatMessageLiveLocation`: `horizontalAccuracy`, `heading`, `proximityAlertRadius`
* New properties in `EditInlineMessageLiveLocation`: `horizontalAccuracy`, `heading`, `proximityAlertRadius`
* Main constructor of `SendLocation` now is internal. Instead of that currently available next factories:
* `SendLocation` - sending of static location without live parameters
* `SendStaticLocation` - sending of static location without live parameters
* `SendLiveLocation` - sending of live location with live parameters
* `PositionedSendMessageRequest` now extends `Locationed`
* `LocationContent#createResend` now can create `LiveLocation`
* Support of `ProximityAlertTriggered`. It is `CommonEvent`
* Property `pollQuestionTextLength` now have maximum up to `300`
* Anonymous Admins:
* New field `AdministratorChatMember#isAnonymous`
* Several new interfaces of messages:
* `SignedMessage` - any message which possibly have `authorSignature`
* `WithSenderChatMessage` - any message which have `senderChat`. Property `senderChat` is not-nullable due to
separation of implementators
* `PublicMessage` - all channel messages have property `val chat: PublicChat` instead of common `val chat: Chat`
* `ChannelMessage` - all channel messages have property `val chat: ChannelChat` instead of common `val chat: Chat`
* Old `ChannelMessage` was safely renamed to `ChannelMessageImpl` (old name was set as typealias and deprecated)
* `GroupMessage` - all group messages have property `val chat: GroupChat` instead of common `val chat: Chat`
* `FromChannelGroupMessage` - instances should have property `val channel: ChannelChat`
* `AnonymousGroupMessage` - instances may have setup property `authorSignature`
* `CommonGroupMessage` - just common message
* `PrivateMessage` - works like previous `CommonMessageImpl`
* Previous `CommonMessageImpl` safely renamed to `PrivateMessageImpl`
* New property `PromoteChatMember#isAnonymous`
* Update all classes which must have `entities`/`caption_entities` fields
* New request `CopyMessage`
* New extension `List<TextSource>#makeString` for more comfortable work with new api with entities
* Support for Google Places identifiers for venues
* New extensions for text sources separating:
* `List<TextSource>#separateForMessage`
* `List<TextSource>#separateForCaption`
* `List<TextSource>#separateForText`
* Rewritten work with text sources and text parts:
* Now any `Message` type with entities will have full list of entities. That means that parts without any
formatter entities will use `RegularTextSource`
* `MultilevelTextSource#textParts` has been deprecated. Now each `MultilevelTextSource` have its own
`textSources` list
* New dsl for creating of `TextSource` lists
* Built-in `handleSafely` and `ExceptionHandler` is deprecated
* New common factories for `StorageFile`
* `API`:
* Extensions `TelegramBot#pinChatMessage` now support any `Chat` and `Message`s from any `Chat`
* New extensions `TelegramBot#unpinAllChatMessages`
* Extensions `TelegramBot#promoteChatMember` got `isAnonymous` parameter
* All old api methods has been actualized to their analogs in `Core`
* All `telegramBot` with `token: String` got `apiUrl` parameter
* Factory `telegramBotWithCustomClientConfig` has been renamed to `telegramBot`
## 0.29.4
* `Core`:

View File

@ -6,16 +6,18 @@ kotlin.incremental=true
kotlin.incremental.js=true
kotlin_version=1.4.10
kotlin_coroutines_version=1.4.0
kotlin_coroutines_version=1.4.1
kotlin_serialisation_runtime_version=1.0.1
klock_version=1.12.1
uuid_version=0.2.2
ktor_version=1.4.1
micro_utils_version=0.2.7
javax_activation_version=1.1.1
library_group=dev.inmo
library_version=0.29.4
library_version=0.30.0
gradle_bintray_plugin_version=1.8.5
github_release_plugin_version=2.2.12

View File

@ -47,6 +47,8 @@ kotlin {
api "com.soywiz.korlibs.klock:klock:$klock_version"
api "com.benasher44:uuid:$uuid_version"
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
api "io.ktor:ktor-client-core:$ktor_version"
}
}

View File

@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
interface Captioned {
val caption: String?
@ -19,8 +19,16 @@ interface CaptionedInput : Captioned {
val captionEntities: List<TextPart>
}
/**
* @see CaptionedInput.captionEntities
* @see justTextSources
*/
val CaptionedInput.textSources
get() = captionEntities.justTextSources()
/**
* Convert its [CaptionedInput.captionEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
*/
fun CaptionedInput.fullEntitiesList(): FullTextSourcesList = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList()
@Deprecated("Currently list of entities already full. This method is redundant")
fun CaptionedInput.fullEntitiesList(): TextSourcesList = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList()

View File

@ -1,8 +1,12 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.*
interface CommonVenueData : Titled {
override val title: String
val address: String
val foursquareId: String?
val foursquareType: String? // TODO:: Rewrite with enum or interface
val foursquareId: FoursquareId?
val foursquareType: FoursquareType? // TODO:: Rewrite with enum or interface
val googlePlaceId: GooglePlaceId?
val googlePlaceType: GooglePlaceType?
}

View File

@ -1,16 +1,22 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
interface Explained {
val explanation: String?
}
interface ExplainedOutput : Explained {
interface ParsableExplainedOutput : Explained {
val parseMode: ParseMode?
}
interface EntitiesExplainedOutput : Explained {
val entities: List<TextSource>?
}
interface ExplainedOutput : ParsableExplainedOutput, EntitiesExplainedOutput
interface ExplainedInput : Explained {
/**
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
@ -19,8 +25,16 @@ interface ExplainedInput : Explained {
val explanationEntities: List<TextPart>
}
/**
* @see ExplainedInput.explanationEntities
* @see justTextSources
*/
val ExplainedInput.textSources
get() = explanationEntities.justTextSources()
/**
* Convert its [ExplainedInput.explanationEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
*/
fun ExplainedInput.fullEntitiesList(): FullTextSourcesList = explanation ?.fullListOfSubSource(explanationEntities) ?.map { it.source } ?: emptyList()
@Deprecated("Currently list of entities already full. This method is redundant")
fun ExplainedInput.fullEntitiesList(): TextSourcesList = explanation ?.fullListOfSubSource(explanationEntities) ?.map { it.source } ?: emptyList()

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Degrees
interface Headed {
val heading: Degrees?
}

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Meters
interface HorizontallyAccured {
val horizontalAccuracy: Meters?
}

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Seconds
interface Livable {
/**
* Period in SECONDS
* Period in [Seconds]
*/
val livePeriod: Int?
val livePeriod: Seconds?
}

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Meters
interface ProximityAlertable {
val proximityAlertRadius: Meters?
}

View File

@ -1,6 +1,16 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.MessageEntity.textsources.regular
import dev.inmo.tgbotapi.types.MessageEntity.toTextParts
import dev.inmo.tgbotapi.types.captionLength
import dev.inmo.tgbotapi.types.textLength
const val DirectInvocationOfTextSourceConstructor = "It is strongly not recommended to use constructors directly instead of factory methods"
typealias TextSourcesList = List<TextSource>
@Deprecated("All lists of TextSource in public API now are full. So, this typealias is redundant")
typealias FullTextSourcesList = List<TextSource>
@Deprecated("All lists of TextPart in public API now are full. So, this typealias is redundant")
typealias FullTextPartsList = List<TextPart>
interface TextSource {
@ -8,11 +18,25 @@ interface TextSource {
val asMarkdownV2Source: String
val asHtmlSource: String
val source: String
val asText: String
get() = source
}
@Suppress("NOTHING_TO_INLINE")
inline operator fun TextSource.plus(other: TextSource) = listOf(this, other)
@Suppress("NOTHING_TO_INLINE")
inline operator fun TextSource.plus(other: List<TextSource>) = listOf(this) + other
@Suppress("NOTHING_TO_INLINE")
inline operator fun TextSource.plus(text: String) = listOf(this, regular(text))
@Suppress("NOTHING_TO_INLINE")
inline operator fun List<TextSource>.plus(text: String) = this + regular(text)
interface MultilevelTextSource : TextSource {
@Deprecated("Will be removed in near major release")
val textParts: List<TextPart>
get() = textParts(0)
val textSources: List<TextSource>
}
data class TextPart(
@ -21,3 +45,49 @@ data class TextPart(
)
fun List<TextPart>.justTextSources() = map { it.source }
fun List<TextSource>.makeString() = joinToString("") { it.source }
internal fun MultilevelTextSource.textParts(offset: Int): List<TextPart> = textSources.toTextParts(offset)
fun List<TextSource>.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List<List<TextSource>> {
if (isEmpty()) {
return emptyList()
}
val resultList = mutableListOf<MutableList<TextSource>>(mutableListOf())
var currentPartLength = 0
val maxSize = limit.last + 1
for (current in this) {
if (current.source.length > maxSize) {
error("Currently unsupported parts with size more than target one-message parts (${current.source.length} > ${maxSize})")
}
if (currentPartLength + current.source.length > maxSize) {
if (numberOfParts == null || numberOfParts < resultList.size) {
resultList.add(mutableListOf())
currentPartLength = 0
} else {
break
}
}
resultList.last().add(current)
currentPartLength += current.source.length
}
return resultList
}
/**
* This method will prepare [TextSource]s list for messages. Remember, that first part will be separated with
* [captionLength] and all others with
*/
fun List<TextSource>.separateForCaption(): List<List<TextSource>> {
val captionPart = separateForMessage(captionLength, 1).first()
return listOf(captionPart) + minus(captionPart).separateForMessage(textLength)
}
/**
* This method will prepare [TextSource]s list for messages with [textLength]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun List<TextSource>.separateForText(): List<List<TextSource>> = separateForMessage(textLength)

View File

@ -0,0 +1,40 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
interface Texted {
val text: String?
}
interface ParsableOutput : Texted {
val parseMode: ParseMode?
}
interface EntitiesOutput : Texted {
val entities: List<TextSource>?
}
interface TextedOutput : ParsableOutput, EntitiesOutput
interface TextedInput : Texted {
/**
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
* @see [CaptionedInput.fullEntitiesList]
*/
val textEntities: List<TextPart>
}
/**
* @see TextedInput.textEntities
* @see justTextSources
*/
val TextedInput.textSources
get() = textEntities.justTextSources()
/**
* Convert its [TextedInput.textEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
*/
@Deprecated("Currently list of entities already full. This method is redundant")
fun TextedInput.fullEntitiesList(): TextSourcesList = text ?.fullListOfSubSource(textEntities) ?.map { it.source } ?: emptyList()

View File

@ -4,4 +4,5 @@ import dev.inmo.tgbotapi.types.MessageIdentifier
interface ReplyMessageId {
val replyToMessageId: MessageIdentifier?
val allowSendingWithoutReply: Boolean?
}

View File

@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.bot.Ktor
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.Ktor.base.*
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
@ -10,7 +11,6 @@ import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.utils.*
import io.ktor.client.HttpClient
import io.ktor.client.features.*
import io.ktor.client.statement.HttpStatement
import io.ktor.client.statement.readText
import kotlinx.serialization.json.Json
@ -37,7 +37,7 @@ class KtorRequestsExecutor(
}
override suspend fun <T : Any> execute(request: Request<T>): T {
return handleSafely(
return safely(
{ e ->
throw if (e is ClientRequestException) {
val content = e.response ?.readText() ?: throw e

View File

@ -1,15 +1,12 @@
package dev.inmo.tgbotapi.bot.Ktor.base
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.requests.DownloadFile
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import dev.inmo.tgbotapi.utils.handleSafely
import io.ktor.client.HttpClient
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.HttpMethod
import io.ktor.client.request.get
import kotlinx.serialization.json.Json
object DownloadFileRequestCallFactory : KtorCallFactory {
@ -21,7 +18,7 @@ object DownloadFileRequestCallFactory : KtorCallFactory {
): T? = (request as? DownloadFile) ?.let {
val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}"
return handleSafely {
return safely {
@Suppress("UNCHECKED_CAST")
client.get<ByteArray>(fullUrl) as T // always ByteArray
}

View File

@ -14,6 +14,8 @@ data class PromoteChatMember(
override val userId: UserId,
@SerialName(untilDateField)
override val untilDate: TelegramDate? = null,
@SerialName(isAnonymousField)
private val isAnonymous: Boolean? = null,
@SerialName(canChangeInfoField)
private val canChangeInfo: Boolean? = null,
@SerialName(canPostMessagesField)

View File

@ -10,7 +10,9 @@ data class UnbanChatMember(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(userIdField)
override val userId: UserId
override val userId: UserId,
@SerialName(onlyIfBannedField)
val onlyIfBanned: Boolean? = null
) : ChatMemberRequest<Boolean> {
override fun method(): String = "unbanChatMember"
override val resultDeserializer: DeserializationStrategy<Boolean>

View File

@ -6,6 +6,11 @@ import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
/**
* Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private chat, the bot
* must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a
* supergroup or 'can_edit_messages' admin right in a channel.
*/
@Serializable
data class PinChatMessage (
@SerialName(chatIdField)

View File

@ -0,0 +1,28 @@
package dev.inmo.tgbotapi.requests.chat.modify
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.chatIdField
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
/**
* Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an
* administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or
* 'can_edit_messages' admin right in a channel.
*
* @see PinChatMessage
* @see UnpinChatMessage
*/
@Serializable
data class UnpinAllChatMessages(
@SerialName(chatIdField)
override val chatId: ChatIdentifier
): ChatRequest, SimpleRequest<Boolean> {
override fun method(): String = "unpinAllChatMessages"
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -3,14 +3,18 @@ package dev.inmo.tgbotapi.requests.chat.modify
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.chatIdField
import dev.inmo.tgbotapi.types.messageIdField
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
data class UnpinChatMessage(
@SerialName(chatIdField)
override val chatId: ChatIdentifier
override val chatId: ChatIdentifier,
@SerialName(messageIdField)
val messageId: MessageIdentifier? = null
): ChatRequest, SimpleRequest<Boolean> {
override fun method(): String = "unpinChatMessage"
override val resultDeserializer: DeserializationStrategy<Boolean>

View File

@ -6,6 +6,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.*
private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>()
@ -20,6 +21,12 @@ data class EditChatMessageLiveLocation(
override val latitude: Double,
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : EditChatMessage<LocationContent>, EditReplyMessage, EditLocationMessage {
@ -28,4 +35,10 @@ data class EditChatMessageLiveLocation(
get() = commonResultDeserializer
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
init {
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
}
}
}

View File

@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.requests.edit.LiveLocation
import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.*
@Serializable
@ -13,10 +14,22 @@ data class EditInlineMessageLiveLocation(
override val latitude: Double,
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : EditInlineMessage, EditReplyMessage, EditLocationMessage {
override fun method(): String = "editMessageLiveLocation"
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
init {
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
}
}
}

View File

@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.requests.edit.abstracts
interface EditLocationMessage {
val latitude: Double
val longitude: Double
}
import dev.inmo.tgbotapi.CommonAbstracts.*
interface EditLocationMessage : Locationed, HorizontallyAccured, ProximityAlertable, Headed

View File

@ -1,8 +1,7 @@
package dev.inmo.tgbotapi.requests.edit.abstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
interface EditTextChatMessage {
val text: String
val parseMode: ParseMode?
interface EditTextChatMessage : TextedOutput {
override val text: String
}

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.requests.edit.caption
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.requests.edit.media.MediaContentMessageResultDeserializer
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -12,8 +14,37 @@ import kotlinx.serialization.*
const val editMessageCaptionMethod = "editMessageCaption"
fun EditChatMessageCaption(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
text: String,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = EditChatMessageCaption(
chatId,
messageId,
text,
parseMode,
null,
replyMarkup
)
fun EditChatMessageCaption(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null
) = EditChatMessageCaption(
chatId,
messageId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
replyMarkup
)
@Serializable
data class EditChatMessageCaption(
data class EditChatMessageCaption internal constructor(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(messageIdField)
@ -22,9 +53,14 @@ data class EditChatMessageCaption(
override val text: String,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : EditChatMessage<MediaContent>, EditTextChatMessage, EditReplyMessage {
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources()
}
override fun method(): String = editMessageCaptionMethod
override val resultDeserializer: DeserializationStrategy<ContentMessage<MediaContent>>

View File

@ -1,23 +1,56 @@
package dev.inmo.tgbotapi.requests.edit.caption
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.*
fun EditInlineMessageCaption(
inlineMessageId: InlineMessageIdentifier,
text: String,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = EditInlineMessageCaption(
inlineMessageId,
text,
parseMode,
null,
replyMarkup
)
fun EditInlineMessageCaption(
inlineMessageId: InlineMessageIdentifier,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null
) = EditInlineMessageCaption(
inlineMessageId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
replyMarkup
)
@Serializable
data class EditInlineMessageCaption(
data class EditInlineMessageCaption internal constructor(
@SerialName(inlineMessageIdField)
override val inlineMessageId: InlineMessageIdentifier,
@SerialName(captionField)
override val text: String,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage {
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources()
}
override fun method(): String = editMessageCaptionMethod
override val requestSerializer: SerializationStrategy<*>
get() = serializer()

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.requests.edit.text
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.requests.send.TextContentMessageResultDeserializer
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -12,8 +14,41 @@ import kotlinx.serialization.*
const val editMessageTextMethod = "editMessageText"
fun EditChatMessageText(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
text: String,
parseMode: ParseMode? = null,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = EditChatMessageText(
chatId,
messageId,
text,
parseMode,
null,
disableWebPagePreview,
replyMarkup
)
fun EditChatMessageText(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
entities: List<TextSource>,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = EditChatMessageText(
chatId,
messageId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
disableWebPagePreview,
replyMarkup
)
@Serializable
data class EditChatMessageText(
data class EditChatMessageText internal constructor(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(messageIdField)
@ -22,11 +57,16 @@ data class EditChatMessageText(
override val text: String,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(entitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableWebPagePreviewField)
override val disableWebPagePreview: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : EditChatMessage<TextContent>, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources()
}
override fun method(): String = editMessageTextMethod
override val resultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>

View File

@ -1,26 +1,63 @@
package dev.inmo.tgbotapi.requests.edit.text
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.requests.edit.media.editMessageMediaMethod
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.*
fun EditInlineMessageText(
inlineMessageId: InlineMessageIdentifier,
text: String,
parseMode: ParseMode? = null,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = EditInlineMessageText(
inlineMessageId,
text,
parseMode,
null,
disableWebPagePreview,
replyMarkup
)
fun EditInlineMessageText(
inlineMessageId: InlineMessageIdentifier,
entities: List<TextSource>,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = EditInlineMessageText(
inlineMessageId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
disableWebPagePreview,
replyMarkup
)
@Serializable
data class EditInlineMessageText(
data class EditInlineMessageText internal constructor(
@SerialName(inlineMessageIdField)
override val inlineMessageId: InlineMessageIdentifier,
@SerialName(textField)
override val text: String,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(entitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableWebPagePreviewField)
override val disableWebPagePreview: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
override fun method(): String = editMessageMediaMethod
override val requestSerializer: SerializationStrategy<*>
get() = serializer()

View File

@ -0,0 +1,23 @@
package dev.inmo.tgbotapi.requests.local
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
/**
* Use this method to close the bot instance before moving it from one local server to another. You need to delete the
* webhook before calling this method to ensure that the bot isn't launched again after server restart. The method will
* return error 429 in the first 10 minutes after the bot is launched.
*
* @see io.ktor.client.features.ClientRequestException
*/
@Serializable
object Close : SimpleRequest<Boolean> {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = "close"
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
}

View File

@ -0,0 +1,21 @@
package dev.inmo.tgbotapi.requests.local
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
/**
* Use this method to log out from the cloud Bot API server before launching the bot locally. You **must** log out the bot
* before running it locally, otherwise there is no guarantee that the bot will receive updates. After a successful
* call, you will not be able to log in again using the same token for 10 minutes
*/
@Serializable
object LogOut : SimpleRequest<Boolean> {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = "logOut"
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
}

View File

@ -0,0 +1,77 @@
package dev.inmo.tgbotapi.requests.send
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.types.MessageAction
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import kotlinx.serialization.*
fun CopyMessage(
fromChatId: ChatIdentifier,
toChatId: ChatIdentifier,
messageId: MessageIdentifier,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = CopyMessage(fromChatId, toChatId, messageId, text, parseMode, null, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
fun CopyMessage(
fromChatId: ChatIdentifier,
toChatId: ChatIdentifier,
messageId: MessageIdentifier,
entities: List<TextSource>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = CopyMessage(fromChatId, toChatId, messageId, entities.makeString(), null, entities.toRawMessageEntities(), disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
@Serializable
data class CopyMessage internal constructor(
@SerialName(fromChatIdField)
val fromChatId: ChatIdentifier,
@SerialName(chatIdField)
val toChatId: ChatIdentifier,
@SerialName(messageIdField)
override val messageId: MessageIdentifier,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
): SimpleRequest<MessageIdentifier>,
ReplyingMarkupSendMessageRequest<MessageIdentifier>,
MessageAction,
TextedOutput {
override val chatId: ChatIdentifier
get() = fromChatId
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
override fun method(): String = "copyMessage"
override val resultDeserializer: DeserializationStrategy<MessageIdentifier>
get() = MessageIdSerializer
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -26,6 +26,8 @@ data class SendContact(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<ContactContent>>,
@ -36,6 +38,7 @@ data class SendContact(
contact: Contact,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): this(
chatId,
@ -44,6 +47,7 @@ data class SendContact(
contact.lastName,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@ -58,11 +62,13 @@ fun Contact.toRequest(
chatId: ChatIdentifier,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): SendContact = SendContact(
chatId,
this,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)

View File

@ -24,6 +24,8 @@ data class SendDice(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : ReplyingMarkupSendMessageRequest<ContentMessage<DiceContent>>, ReplyMessageId, DisableNotification {

View File

@ -1,19 +1,79 @@
package dev.inmo.tgbotapi.requests.send
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.*
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
= TelegramBotAPIMessageDeserializationStrategyClass()
fun SendLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendLocation(
chatId,
latitude,
longitude,
null,
null,
null,
null,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
fun SendStaticLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendLocation(chatId, latitude, longitude, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
fun SendLiveLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendLocation(
chatId,
latitude,
longitude,
livePeriod,
horizontalAccuracy,
heading,
proximityAlertRadius,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@Serializable
data class SendLocation(
data class SendLocation internal constructor(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(latitudeField)
@ -21,16 +81,28 @@ data class SendLocation(
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(livePeriodField)
val livePeriod: Long? = null,
override val livePeriod: Seconds? = null,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<LocationContent>>,
ReplyingMarkupSendMessageRequest<ContentMessage<LocationContent>>,
PositionedSendMessageRequest<ContentMessage<LocationContent>>
PositionedSendMessageRequest<ContentMessage<LocationContent>>,
HorizontallyAccured,
Livable,
ProximityAlertable,
Headed
{
override fun method(): String = "sendLocation"
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
@ -42,5 +114,8 @@ data class SendLocation(
if (livePeriod != null && livePeriod !in livePeriodLimit) {
error("Live period for sending location must be in $livePeriodLimit, but was $livePeriod")
}
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
}
}
}

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.requests.send
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.types.DisableWebPagePreview
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -15,20 +17,65 @@ import kotlinx.serialization.*
internal val TextContentMessageResultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>
= TelegramBotAPIMessageDeserializationStrategyClass()
fun SendTextMessage(
chatId: ChatIdentifier,
text: String,
parseMode: ParseMode? = null,
disableWebPagePreview: Boolean? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendTextMessage(
chatId,
text,
parseMode,
null,
disableWebPagePreview,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
fun SendTextMessage(
chatId: ChatIdentifier,
entities: List<TextSource>,
disableWebPagePreview: Boolean? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendTextMessage(
chatId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
disableWebPagePreview,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@Serializable
data class SendTextMessage(
data class SendTextMessage internal constructor(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(textField)
override val text: String,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(entitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableWebPagePreviewField)
override val disableWebPagePreview: Boolean? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<TextContent>>,
@ -36,6 +83,10 @@ data class SendTextMessage(
TextableSendMessageRequest<ContentMessage<TextContent>>,
DisableWebPagePreview
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources()
}
init {
if (text.length !in textLength) {
throwRangeError("Text length", textLength, text.length)

View File

@ -25,11 +25,19 @@ data class SendVenue(
@SerialName(addressField)
val address: String,
@SerialName(foursquareIdField)
val foursquareId: String? = null,
val foursquareId: FoursquareId? = null,
@SerialName(foursquareTypeField)
val foursquareType: FoursquareType? = null,
@SerialName(googlePlaceIdField)
val googlePlaceId: GooglePlaceId? = null,
@SerialName(googlePlaceTypeField)
val googlePlaceType: GooglePlaceType? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<VenueContent>>,
@ -42,17 +50,22 @@ data class SendVenue(
venue: Venue,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): this(
chatId,
venue.location.latitude,
venue.location.longitude,
venue.title,
venue.address,
venue.foursquareId,
disableNotification,
replyToMessageId,
replyMarkup
chatId = chatId,
latitude = venue.location.latitude,
longitude = venue.location.longitude,
title = venue.title,
address = venue.address,
foursquareId = venue.foursquareId,
foursquareType = venue.foursquareType,
googlePlaceId = venue.googlePlaceId,
googlePlaceType = venue.googlePlaceType,
disableNotification = disableNotification,
replyToMessageId = replyToMessageId,
allowSendingWithoutReply = allowSendingWithoutReply,
replyMarkup = replyMarkup
)
override fun method(): String = "sendVenue"
@ -66,11 +79,13 @@ fun Venue.toRequest(
chatId: ChatIdentifier,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): SendVenue = SendVenue(
chatId,
this,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)

View File

@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.requests.send.abstracts
interface PositionedSendMessageRequest<T: Any>: SendMessageRequest<T> {
val latitude: Double
val longitude: Double
}
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
interface PositionedSendMessageRequest<T: Any>: SendMessageRequest<T>, Locationed

View File

@ -1,8 +1,5 @@
package dev.inmo.tgbotapi.requests.send.abstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
interface TextableSendMessageRequest<T: Any>: SendMessageRequest<T> {
val text: String?
val parseMode: ParseMode?
}
interface TextableSendMessageRequest<T: Any>: SendMessageRequest<T>, TextedOutput

View File

@ -22,6 +22,8 @@ data class SendGame (
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<GameContent>>,

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -25,6 +27,7 @@ fun SendAnimation(
height: Int? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<AnimationContent>> {
val animationAsFileId = (animation as? FileId) ?.fileId
@ -38,11 +41,57 @@ fun SendAnimation(
thumbAsFileId,
caption,
parseMode,
null,
duration,
width,
height,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
return if (animationAsFile == null && thumbAsFile == null) {
data
} else {
MultipartRequestImpl(
data,
SendAnimationFiles(animationAsFile, thumbAsFile)
)
}
}
fun SendAnimation(
chatId: ChatIdentifier,
animation: InputFile,
thumb: InputFile? = null,
entities: List<TextSource>,
duration: Long? = null,
width: Int? = null,
height: Int? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<AnimationContent>> {
val animationAsFileId = (animation as? FileId) ?.fileId
val animationAsFile = animation as? MultipartFile
val thumbAsFileId = (thumb as? FileId) ?.fileId
val thumbAsFile = thumb as? MultipartFile
val data = SendAnimationData(
chatId,
animationAsFileId,
thumbAsFileId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
duration,
width,
height,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@ -71,6 +120,8 @@ data class SendAnimationData internal constructor(
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(durationField)
override val duration: Long? = null,
@SerialName(widthField)
@ -81,6 +132,8 @@ data class SendAnimationData internal constructor(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : DataRequest<ContentMessage<AnimationContent>>,
@ -91,6 +144,10 @@ data class SendAnimationData internal constructor(
DuratedSendMessageRequest<ContentMessage<AnimationContent>>,
SizedSendMessageRequest<ContentMessage<AnimationContent>>
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
text ?.let {
if (it.length !in captionLength) {

View File

@ -1,10 +1,11 @@
package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.Performerable
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -26,6 +27,7 @@ fun SendAudio(
title: String? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<AudioContent>> {
val audioAsFileId = (audio as? FileId) ?.fileId
@ -39,11 +41,57 @@ fun SendAudio(
thumbAsFileId,
caption,
parseMode,
null,
duration,
performer,
title,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
return if (audioAsFile == null && thumbAsFile == null) {
data
} else {
MultipartRequestImpl(
data,
SendAudioFiles(audioAsFile, thumbAsFile)
)
}
}
fun SendAudio(
chatId: ChatIdentifier,
audio: InputFile,
thumb: InputFile? = null,
entities: List<TextSource>,
duration: Long? = null,
performer: String? = null,
title: String? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<AudioContent>> {
val audioAsFileId = (audio as? FileId) ?.fileId
val audioAsFile = audio as? MultipartFile
val thumbAsFileId = (thumb as? FileId) ?.fileId
val thumbAsFile = thumb as? MultipartFile
val data = SendAudioData(
chatId,
audioAsFileId,
thumbAsFileId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
duration,
performer,
title,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@ -72,6 +120,8 @@ data class SendAudioData internal constructor(
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(durationField)
override val duration: Long? = null,
@SerialName(performerField)
@ -82,6 +132,8 @@ data class SendAudioData internal constructor(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : DataRequest<ContentMessage<AudioContent>>,
@ -93,6 +145,10 @@ data class SendAudioData internal constructor(
DuratedSendMessageRequest<ContentMessage<AudioContent>>,
Performerable
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
text ?.let {
if (it.length !in captionLength) {

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -14,6 +16,15 @@ import dev.inmo.tgbotapi.utils.mapOfNotNull
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.*
/**
* Use this method to send general files. On success, the sent [ContentMessage] with [DocumentContent] is returned.
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
*
* @param disableContentTypeDetection Disables automatic server-side content type detection for [document] [MultipartFile]
*
* @see ContentMessage
* @see DocumentContent
*/
fun SendDocument(
chatId: ChatIdentifier,
document: InputFile,
@ -22,7 +33,9 @@ fun SendDocument(
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null,
disableContentTypeDetection: Boolean? = null
): Request<ContentMessage<DocumentContent>> {
val documentAsFileId = (document as? FileId) ?.fileId
val documentAsFile = document as? MultipartFile
@ -35,9 +48,61 @@ fun SendDocument(
thumbAsFileId,
caption,
parseMode,
null,
disableNotification,
replyToMessageId,
replyMarkup
allowSendingWithoutReply,
replyMarkup,
disableContentTypeDetection
)
return if (documentAsFile == null && thumbAsFile == null) {
data
} else {
MultipartRequestImpl(
data,
SendDocumentFiles(documentAsFile, thumbAsFile)
)
}
}
/**
* Use this method to send general files. On success, the sent [ContentMessage] with [DocumentContent] is returned.
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
*
* @param disableContentTypeDetection Disables automatic server-side content type detection for [document] [MultipartFile]
*
* @see ContentMessage
* @see DocumentContent
*/
fun SendDocument(
chatId: ChatIdentifier,
document: InputFile,
thumb: InputFile? = null,
entities: List<TextSource>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null,
disableContentTypeDetection: Boolean? = null
): Request<ContentMessage<DocumentContent>> {
val documentAsFileId = (document as? FileId) ?.fileId
val documentAsFile = document as? MultipartFile
val thumbAsFileId = (thumb as? FileId) ?.fileId
val thumbAsFile = thumb as? MultipartFile
val data = SendDocumentData(
chatId,
documentAsFileId,
thumbAsFileId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup,
disableContentTypeDetection
)
return if (documentAsFile == null && thumbAsFile == null) {
@ -53,6 +118,15 @@ fun SendDocument(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<DocumentContent>>
= TelegramBotAPIMessageDeserializationStrategyClass()
/**
* Use this method to send general files. On success, the sent [ContentMessage] with [DocumentContent] is returned.
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
*
* @param disableContentTypeDetection Disables automatic server-side content type detection for [document] [MultipartFile]
*
* @see ContentMessage
* @see DocumentContent
*/
@Serializable
data class SendDocumentData internal constructor(
@SerialName(chatIdField)
@ -65,18 +139,28 @@ data class SendDocumentData internal constructor(
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
override val replyMarkup: KeyboardMarkup? = null,
@SerialName(disableContentTypeDetectionField)
val disableContentTypeDetection: Boolean? = null
) : DataRequest<ContentMessage<DocumentContent>>,
SendMessageRequest<ContentMessage<DocumentContent>>,
ReplyingMarkupSendMessageRequest<ContentMessage<DocumentContent>>,
TextableSendMessageRequest<ContentMessage<DocumentContent>>,
ThumbedSendMessageRequest<ContentMessage<DocumentContent>>
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
text ?.let {
if (it.length !in captionLength) {

View File

@ -9,7 +9,6 @@ import dev.inmo.tgbotapi.types.InputMedia.*
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.buildJsonArray
@ -22,7 +21,8 @@ fun SendMediaGroup(
chatId: ChatIdentifier,
media: List<MediaGroupMemberInputMedia>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
): Request<List<MediaGroupMessage>> {
if (media.size !in mediaCountInMediaGroup) {
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
@ -43,7 +43,8 @@ fun SendMediaGroup(
chatId,
media,
disableNotification,
replyToMessageId
replyToMessageId,
allowSendingWithoutReply
)
return if (files.isEmpty()) {
@ -66,8 +67,9 @@ inline fun SendPlaylist(
chatId: ChatIdentifier,
media: List<AudioMediaGroupMemberInputMedia>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId)
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
/**
* Use this method to be sure that you are correctly sending documents media group
@ -79,8 +81,9 @@ inline fun SendDocumentsGroup(
chatId: ChatIdentifier,
media: List<DocumentMediaGroupMemberInputMedia>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId)
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
/**
* Use this method to be sure that you are correctly sending visual media group
@ -93,8 +96,9 @@ inline fun SendVisualMediaGroup(
chatId: ChatIdentifier,
media: List<VisualMediaGroupMemberInputMedia>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId)
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
private val messagesListSerializer: KSerializer<List<MediaGroupMessage>>
= ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass())
@ -107,7 +111,9 @@ data class SendMediaGroupData internal constructor(
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null
) : DataRequest<List<MediaGroupMessage>>, SendMessageRequest<List<MediaGroupMessage>> {
@SerialName(mediaField)
private val convertedMedia: String

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -20,6 +22,7 @@ fun SendPhoto(
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<PhotoContent>> {
val data = SendPhotoData(
@ -27,8 +30,38 @@ fun SendPhoto(
(photo as? FileId) ?.fileId,
caption,
parseMode,
null,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
return data.photo ?.let {
data
} ?: MultipartRequestImpl(
data,
SendPhotoFiles(photo as MultipartFile)
)
}
fun SendPhoto(
chatId: ChatIdentifier,
photo: InputFile,
entities: List<TextSource>,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<PhotoContent>> {
val data = SendPhotoData(
chatId,
(photo as? FileId) ?.fileId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
return data.photo ?.let {
@ -52,10 +85,14 @@ data class SendPhotoData internal constructor(
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : DataRequest<ContentMessage<PhotoContent>>,
@ -63,6 +100,10 @@ data class SendPhotoData internal constructor(
ReplyingMarkupSendMessageRequest<ContentMessage<PhotoContent>>,
TextableSendMessageRequest<ContentMessage<PhotoContent>>
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
text ?.let {
if (it.length !in captionLength) {

View File

@ -17,12 +17,14 @@ fun SendSticker(
sticker: InputFile,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<StickerContent>> = SendStickerByFileId(
chatId,
sticker as? FileId,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
).let {
when (sticker) {
@ -44,6 +46,8 @@ data class SendStickerByFileId internal constructor(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<StickerContent>>, ReplyingMarkupSendMessageRequest<ContentMessage<StickerContent>> {

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -26,6 +28,7 @@ fun SendVideo(
supportStreaming: Boolean? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<VideoContent>> {
val videoAsFileId = (video as? FileId) ?.fileId
@ -39,12 +42,60 @@ fun SendVideo(
thumbAsFileId,
caption,
parseMode,
null,
duration,
width,
height,
supportStreaming,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
return if (videoAsFile == null && thumbAsFile == null) {
data
} else {
MultipartRequestImpl(
data,
SendVideoFiles(videoAsFile, thumbAsFile)
)
}
}
fun SendVideo(
chatId: ChatIdentifier,
video: InputFile,
thumb: InputFile? = null,
entities: List<TextSource>,
duration: Long? = null,
width: Int? = null,
height: Int? = null,
supportStreaming: Boolean? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<VideoContent>> {
val videoAsFileId = (video as? FileId) ?.fileId
val videoAsFile = video as? MultipartFile
val thumbAsFileId = (thumb as? FileId) ?.fileId
val thumbAsFile = thumb as? MultipartFile
val data = SendVideoData(
chatId,
videoAsFileId,
thumbAsFileId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
duration,
width,
height,
supportStreaming,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@ -73,6 +124,8 @@ data class SendVideoData internal constructor(
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(durationField)
override val duration: Long? = null,
@SerialName(widthField)
@ -85,6 +138,8 @@ data class SendVideoData internal constructor(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : DataRequest<ContentMessage<VideoContent>>,
@ -95,6 +150,10 @@ data class SendVideoData internal constructor(
DuratedSendMessageRequest<ContentMessage<VideoContent>>,
SizedSendMessageRequest<ContentMessage<VideoContent>>
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
text ?.let {
if (it.length !in captionLength) {

View File

@ -4,26 +4,22 @@ import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import dev.inmo.tgbotapi.types.message.content.media.VideoNoteContent
import dev.inmo.tgbotapi.utils.mapOfNotNull
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.*
fun SendVideoNote(
chatId: ChatIdentifier,
videoNote: InputFile,
thumb: InputFile? = null,
caption: String? = null,
parseMode: ParseMode? = null,
duration: Long? = null,
size: Int? = null, // in documentation - length (size of video side)
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<VideoNoteContent>> {
val videoNoteAsFileId = (videoNote as? FileId) ?.fileId
@ -35,12 +31,11 @@ fun SendVideoNote(
chatId,
videoNoteAsFileId,
thumbAsFileId,
caption,
parseMode,
duration,
size,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@ -65,10 +60,6 @@ data class SendVideoNoteData internal constructor(
val videoNote: String? = null,
@SerialName(thumbField)
override val thumb: String? = null,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(durationField)
override val duration: Long? = null,
@SerialName(lengthField)
@ -77,12 +68,13 @@ data class SendVideoNoteData internal constructor(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : DataRequest<ContentMessage<VideoNoteContent>>,
SendMessageRequest<ContentMessage<VideoNoteContent>>,
ReplyingMarkupSendMessageRequest<ContentMessage<VideoNoteContent>>,
TextableSendMessageRequest<ContentMessage<VideoNoteContent>>,
ThumbedSendMessageRequest<ContentMessage<VideoNoteContent>>,
DuratedSendMessageRequest<ContentMessage<VideoNoteContent>>,
SizedSendMessageRequest<ContentMessage<VideoNoteContent>>
@ -90,14 +82,6 @@ data class SendVideoNoteData internal constructor(
override val height: Int?
get() = width
init {
text ?.let {
if (it.length !in captionLength) {
throwRangeError("Caption length", captionLength, it.length)
}
}
}
override fun method(): String = "sendVideoNote"
override val resultDeserializer: DeserializationStrategy<ContentMessage<VideoNoteContent>>
get() = commonResultDeserializer

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
@ -22,6 +24,7 @@ fun SendVoice(
duration: Long? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<VoiceContent>> {
val voiceAsFileId = (voice as? FileId) ?.fileId
@ -32,9 +35,47 @@ fun SendVoice(
voiceAsFileId,
caption,
parseMode,
null,
duration,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
return if (voiceAsFile == null) {
data
} else {
MultipartRequestImpl(
data,
SendVoiceFiles(voiceAsFile)
)
}
}
fun SendVoice(
chatId: ChatIdentifier,
voice: InputFile,
entities: List<TextSource>,
duration: Long? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<ContentMessage<VoiceContent>> {
val voiceAsFileId = (voice as? FileId) ?.fileId
val voiceAsFile = voice as? MultipartFile
val data = SendVoiceData(
chatId,
voiceAsFileId,
entities.makeString(),
null,
entities.toRawMessageEntities(),
duration,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@ -61,12 +102,16 @@ data class SendVoiceData internal constructor(
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(durationField)
override val duration: Long? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : DataRequest<ContentMessage<VoiceContent>>,
@ -75,6 +120,10 @@ data class SendVoiceData internal constructor(
TextableSendMessageRequest<ContentMessage<VoiceContent>>,
DuratedSendMessageRequest<ContentMessage<VoiceContent>>
{
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
text ?.let {
if (it.length !in captionLength) {

View File

@ -57,6 +57,8 @@ data class SendInvoice(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null
) : Currencied,

View File

@ -1,19 +1,17 @@
package dev.inmo.tgbotapi.requests.send.polls
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import dev.inmo.tgbotapi.types.message.content.PollContent
import dev.inmo.tgbotapi.types.polls.*
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
import com.soywiz.klock.DateTime
import kotlinx.serialization.*
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PollContent>> = TelegramBotAPIMessageDeserializationStrategyClass()
@ -43,6 +41,7 @@ fun SendPoll(
isClosed: Boolean = false,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendRegularPoll(
chatId,
@ -50,6 +49,7 @@ fun SendPoll(
options,
isAnonymous,
isClosed,
allowSendingWithoutReply = allowSendingWithoutReply,
disableNotification = disableNotification,
replyToMessageId = replyToMessageId,
replyMarkup = replyMarkup
@ -63,6 +63,7 @@ fun Poll.createRequest(
chatId: ChatIdentifier,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = when (this) {
is RegularPoll -> SendRegularPoll(
@ -75,6 +76,7 @@ fun Poll.createRequest(
scheduledCloseInfo,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
is QuizPoll -> correctOptionId ?.let { correctOptionId ->
@ -85,11 +87,11 @@ fun Poll.createRequest(
correctOptionId,
isAnonymous,
isClosed,
explanation ?.fullListOfSubSource(explanationEntities) ?.justTextSources() ?.toMarkdownV2Captions() ?.firstOrNull(),
MarkdownV2,
fullEntitiesList(),
scheduledCloseInfo,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
} ?: SendRegularPoll(
@ -102,6 +104,7 @@ fun Poll.createRequest(
scheduledCloseInfo,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
is UnknownPollType -> SendRegularPoll(
@ -114,6 +117,7 @@ fun Poll.createRequest(
scheduledCloseInfo,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
}
@ -165,6 +169,8 @@ data class SendRegularPoll(
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendPoll() {
@ -186,8 +192,69 @@ data class SendRegularPoll(
}
}
fun SendQuizPoll(
chatId: ChatIdentifier,
question: String,
options: List<String>,
correctOptionId: Int,
isAnonymous: Boolean = true,
isClosed: Boolean = false,
explanation: String? = null,
parseMode: ParseMode? = null,
closeInfo: ScheduledCloseInfo? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendQuizPoll(
chatId,
question,
options,
correctOptionId,
isAnonymous,
isClosed,
explanation,
parseMode,
null,
closeInfo,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
fun SendQuizPoll(
chatId: ChatIdentifier,
question: String,
options: List<String>,
correctOptionId: Int,
isAnonymous: Boolean = true,
isClosed: Boolean = false,
entities: List<TextSource>,
closeInfo: ScheduledCloseInfo? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = SendQuizPoll(
chatId,
question,
options,
correctOptionId,
isAnonymous,
isClosed,
entities.makeString(),
null,
entities.toRawMessageEntities(),
closeInfo,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
@Serializable
data class SendQuizPoll(
data class SendQuizPoll internal constructor(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(questionField)
@ -204,18 +271,25 @@ data class SendQuizPoll(
override val explanation: String? = null,
@SerialName(explanationParseModeField)
override val parseMode: ParseMode? = null,
@SerialName(explanationEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@Transient
override val closeInfo: ScheduledCloseInfo? = null,
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null,
@SerialName(replyMarkupField)
override val replyMarkup: KeyboardMarkup? = null
) : SendPoll(), ExplainedOutput {
override val type: String = quizPollType
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(explanation ?: return@lazy null) ?.justTextSources()
}
@SerialName(openPeriodField)
override val openPeriod: LongSeconds?

View File

@ -16,14 +16,18 @@ private fun correctWebhookUrl(sourceUrl: String) = if (sourceUrl.contains("://")
fun SetWebhook(
url: String,
certificate: MultipartFile,
ipAddress: String? = null,
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): MultipartRequestImpl<SetWebhook, Map<String, MultipartFile>, Boolean> = MultipartRequestImpl(
SetWebhook(
correctWebhookUrl(url),
null,
null as String?,
ipAddress,
maxAllowedConnections,
allowedUpdates
allowedUpdates,
dropPendingUpdates
),
mapOf(certificateField to certificate)
)
@ -31,47 +35,83 @@ fun SetWebhook(
fun SetWebhook(
url: String,
certificate: FileId,
ipAddress: String? = null,
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): SetWebhook = SetWebhook(
correctWebhookUrl(url),
certificate.fileId,
ipAddress,
maxAllowedConnections,
allowedUpdates
allowedUpdates,
dropPendingUpdates
)
/**
* Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update
* for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update.
*
* If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the [url],
* e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
*/
@Suppress("USELESS_CAST")
fun SetWebhook(
url: String,
certificate: InputFile,
ipAddress: String? = null,
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): Request<Boolean> = when (certificate) {
is MultipartFile -> SetWebhook(correctWebhookUrl(url), certificate as MultipartFile, maxAllowedConnections, allowedUpdates)
is FileId -> SetWebhook(correctWebhookUrl(url), certificate as FileId, maxAllowedConnections, allowedUpdates)
is MultipartFile -> SetWebhook(correctWebhookUrl(url), certificate as MultipartFile, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates)
is FileId -> SetWebhook(correctWebhookUrl(url), certificate as FileId, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates)
}
/**
* Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update
* for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update.
*
* If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the [url],
* e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
*/
@Suppress("USELESS_CAST")
fun SetWebhook(
url: String,
ipAddress: String? = null,
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null
) = SetWebhook(
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): Request<Boolean> = SetWebhook(
correctWebhookUrl(url),
null,
ipAddress,
maxAllowedConnections,
allowedUpdates
allowedUpdates,
dropPendingUpdates
)
/**
* Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update
* for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update.
*
* If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the [url],
* e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
*/
@Serializable
data class SetWebhook internal constructor(
@SerialName(urlField)
val url: String,
@SerialName(certificateField)
val certificateFile: String? = null,
@SerialName(ipAddressField)
val ipAddress: String? = null,
@SerialName(maxAllowedConnectionsField)
val maxAllowedConnections: Int? = null,
@SerialName(allowedUpdatesField)
val allowedUpdates: List<String>? = null
val allowedUpdates: List<String>? = null,
@SerialName(dropPendingUpdatesField)
val dropPendingUpdates: Boolean? = null
) : DataRequest<Boolean> {
override fun method(): String = "setWebhook"
override val resultDeserializer: DeserializationStrategy<Boolean>

View File

@ -3,7 +3,8 @@ package dev.inmo.tgbotapi.types
import kotlinx.serialization.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.longOrNull
@Serializable(ChatIdentifierSerializer::class)
sealed class ChatIdentifier

View File

@ -0,0 +1,19 @@
package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.types.location.StaticLocation
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Represents a location to which a chat is connected.
*
* @see dev.inmo.tgbotapi.requests.chat.get.GetChat
* @see dev.inmo.tgbotapi.types.chat.abstracts.extended.ExtendedSupergroupChat
*/
@Serializable
data class ChatLocation(
@SerialName(locationField)
val location: StaticLocation,
@SerialName(addressField)
val address: String
)

View File

@ -14,5 +14,6 @@ data class AdministratorChatMemberImpl(
override val canRestrictMembers: Boolean,
override val canPinMessages: Boolean,
override val canPromoteMembers: Boolean,
override val isAnonymous: Boolean,
override val customTitle: String?
) : AdministratorChatMember

View File

@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.types.User
data class CreatorChatMember(
override val user: User,
override val isAnonymous: Boolean,
override val customTitle: String?
) : AdministratorChatMember {
override val canBeEdited: Boolean = true

View File

@ -40,12 +40,14 @@ internal data class RawChatMember(
private val canSendOtherMessages: Boolean = false,
@SerialName(canAddWebPagePreviewsField)
private val canAddWebPagePreviews: Boolean = false,
@SerialName(isAnonymousField)
private val isAnonymous: Boolean = false,
@SerialName(customTitleField)
private val customTitle: String? = null
) {
val asChatMember: ChatMember by lazy {
when (status) {
"creator" -> CreatorChatMember(user, customTitle)
"creator" -> CreatorChatMember(user, isAnonymous, customTitle)
"administrator" -> AdministratorChatMemberImpl(
user,
canBeEdited,
@ -57,6 +59,7 @@ internal data class RawChatMember(
canRestrictMembers,
canPinMessages,
canPromoteMembers,
isAnonymous,
customTitle
)
"member" -> MemberChatMember(user)

View File

@ -7,5 +7,6 @@ interface AdministratorChatMember : SpecialRightsChatMember {
val canRemoveMessages: Boolean
val canRestrictMembers: Boolean
val canPromoteMembers: Boolean
val isAnonymous: Boolean
val customTitle: String?
}

View File

@ -2,7 +2,8 @@ package dev.inmo.tgbotapi.types.ChatMember.abstracts
import dev.inmo.tgbotapi.types.ChatMember.RawChatMember
import dev.inmo.tgbotapi.types.User
import kotlinx.serialization.*
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

View File

@ -24,10 +24,18 @@ typealias FileUniqueId = String
typealias DiceResult = Int
typealias FoursquareId = String
typealias FoursquareType = String
typealias GooglePlaceId = String
typealias GooglePlaceType = String
typealias Seconds = Int
typealias LongSeconds = Long
typealias Meters = Float
typealias Degrees = Int
val degreesLimit = 1 .. 360
val horizontalAccuracyLimit = 0F .. 1500F
val getUpdatesLimit = 1 .. 100
val callbackQueryAnswerLength = 0 until 200
val captionLength = 0 .. 1024
@ -43,7 +51,7 @@ val invoiceDescriptionLimit = 1 until 256
val invoicePayloadBytesLimit = 1 until 128
val pollOptionTextLength = 1 .. 100
val pollQuestionTextLength = 1 until 256
val pollQuestionTextLength = 1 .. 300
val pollOptionsLimit = 2 .. 10
val livePeriodLimit = 60 .. 86400
@ -52,10 +60,11 @@ val inlineQueryAnswerResultsLimit = 0 .. 50
val customTitleLength = 0 .. 16
val commonDiceResultLimit = 1 .. 6
@Deprecated("Renamed", ReplaceWith("commonDiceResultLimit", "dev.inmo.tgbotapi.types.commonDiceResultLimit"))
val dartsAndCubeDiceResultLimit = 1 .. 6
@Deprecated("Renamed", ReplaceWith("dartsAndCubeDiceResultLimit", "dev.inmo.tgbotapi.types.dartsAndCubeDiceResultLimit"))
val diceResultLimit
get() = commonDiceResultLimit
get() = dartsAndCubeDiceResultLimit
val basketballAndFootballDiceResultLimit = 1 .. 5
val slotMachineDiceResultLimit = 1 .. 64
val botCommandLengthLimit = 1 .. 32
@ -85,9 +94,12 @@ const val fromChatIdField = "from_chat_id"
const val disableWebPagePreviewField = "disable_web_page_preview"
const val disableNotificationField = "disable_notification"
const val replyToMessageIdField = "reply_to_message_id"
const val allowSendingWithoutReplyField = "allow_sending_without_reply"
const val replyMarkupField = "reply_markup"
const val disableContentTypeDetectionField = "disable_content_type_detection"
const val supportStreamingField = "support_streaming"
const val livePeriodField = "live_period"
const val proximityAlertRadiusField = "proximity_alert_radius"
const val isBotField = "is_bot"
const val firstNameField = "first_name"
const val lastNameField = "last_name"
@ -96,12 +108,14 @@ const val canJoinGroupsField = "can_join_groups"
const val canReadAllGroupMessagesField = "can_read_all_group_messages"
const val supportInlineQueriesField = "supports_inline_queries"
const val textEntitiesField = "text_entities"
const val entitiesField = "entities"
const val stickerSetNameField = "set_name"
const val stickerSetNameFullField = "sticker_set_name"
const val slowModeDelayField = "slow_mode_delay"
const val maskPositionField = "mask_position"
const val phoneNumberField = "phone_number"
const val userIdField = "user_id"
const val onlyIfBannedField = "only_if_banned"
const val containsMasksField = "contains_masks"
const val resultIdField = "result_id"
const val inlineMessageIdField = "inline_message_id"
@ -114,6 +128,8 @@ const val showAlertField = "show_alert"
const val cachedTimeField = "cached_time"
const val foursquareIdField = "foursquare_id"
const val foursquareTypeField = "foursquare_type"
const val googlePlaceIdField = "google_place_id"
const val googlePlaceTypeField = "google_place_type"
const val untilDateField = "until_date"
const val errorMessageField = "error_message"
const val messageTextField = "message_text"
@ -123,6 +139,7 @@ const val switchPmTextField = "switch_pm_text"
const val switchPmParameterField = "switch_pm_parameter"
const val maxAllowedConnectionsField = "max_connections"
const val allowedUpdatesField = "allowed_updates"
const val dropPendingUpdatesField = "drop_pending_updates"
const val hasCustomCertificateField = "has_custom_certificate"
const val pendingUpdateCountField = "pending_update_count"
const val lastErrorDateField = "last_error_date"
@ -133,6 +150,7 @@ const val totalVoterCountField = "total_voter_count"
const val correctOptionIdField = "correct_option_id"
const val allowsMultipleAnswersField = "allows_multiple_answers"
const val isAnonymousField = "is_anonymous"
const val captionEntitiesField = "caption_entities"
const val loginUrlField = "login_url"
const val forwardTextField = "forward_text"
const val botUsernameField = "bot_username"
@ -143,6 +161,9 @@ const val inviteLinkField = "invite_link"
const val pinnedMessageField = "pinned_message"
const val customTitleField = "custom_title"
const val optionIdsField = "option_ids"
const val ipAddressField = "ip_address"
const val linkedChatIdField = "linked_chat_id"
const val horizontalAccuracyField = "horizontal_accuracy"
const val requestContactField = "request_contact"
const val requestLocationField = "request_location"
@ -240,11 +261,13 @@ const val heightField = "height"
const val lengthField = "length"
const val latitudeField = "latitude"
const val longitudeField = "longitude"
const val headingField = "heading"
const val fromField = "from"
const val userField = "user"
const val dateField = "date"
const val chatField = "chat"
const val usernameField = "username"
const val bioField = "bio"
const val nameField = "name"
const val emailField = "email"
const val locationField = "location"

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.ChosenInlineResult
import dev.inmo.tgbotapi.types.location.StaticLocation
data class LocationChosenInlineResult(
override val resultId: InlineQueryIdentifier,
override val user: User,
val location: Location,
val location: StaticLocation,
override val inlineMessageId: InlineMessageIdentifier?,
override val query: String
) : ChosenInlineResult

View File

@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.ChosenInlineResult
import dev.inmo.tgbotapi.types.location.StaticLocation
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@ -14,7 +15,7 @@ internal data class RawChosenInlineResult(
@SerialName(queryField)
val query: String,
@SerialName(locationField)
val location: Location? = null,
val location: StaticLocation? = null,
@SerialName(inlineMessageIdField)
val inlineMessageId: InlineMessageIdentifier? = null
) {

View File

@ -1,30 +1,54 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultAudioType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultAudioCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultAudioCachedImpl(id, fileId, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultAudioCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultAudioCachedImpl(id, fileId, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultAudioCachedImpl(
data class InlineQueryResultAudioCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(audioFileIdField)
override val fileId: FileId,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultAudioCached {
override val type: String = inlineQueryResultAudioType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,17 +1,42 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultAudioType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultAudioImpl(
id: InlineQueryIdentifier,
url: String,
title: String,
performer: String? = null,
duration: Int? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultAudioImpl(id, url, title, performer, duration, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultAudioImpl(
id: InlineQueryIdentifier,
url: String,
title: String,
performer: String? = null,
duration: Int? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultAudioImpl(id, url, title, performer, duration, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultAudioImpl(
data class InlineQueryResultAudioImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(audioUrlField)
@ -23,13 +48,18 @@ data class InlineQueryResultAudioImpl(
@SerialName(audioDurationField)
override val duration: Int? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultAudio {
override val type: String = inlineQueryResultAudioType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,18 +1,41 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultDocumentType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultDocumentCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String,
description: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultDocumentCachedImpl(id, fileId, title, description, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultDocumentCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String,
description: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultDocumentCachedImpl(id, fileId, title, description, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultDocumentCachedImpl(
data class InlineQueryResultDocumentCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(documentFileIdField)
@ -22,13 +45,18 @@ data class InlineQueryResultDocumentCachedImpl(
@SerialName(descriptionField)
override val description: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultDocumentCached {
override val type: String = inlineQueryResultDocumentType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultDocumentType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -12,8 +14,37 @@ import dev.inmo.tgbotapi.utils.MimeType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultDocumentImpl(
id: InlineQueryIdentifier,
url: String,
title: String,
mimeType: MimeType,
thumbUrl: String? = null,
thumbWidth: Int? = null,
thumbHeight: Int? = null,
description: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultDocumentImpl(id, url, title, mimeType, thumbUrl, thumbWidth, thumbHeight, description, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultDocumentImpl(
id: InlineQueryIdentifier,
url: String,
title: String,
mimeType: MimeType,
thumbUrl: String? = null,
thumbWidth: Int? = null,
thumbHeight: Int? = null,
description: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultDocumentImpl(id, url, title, mimeType, thumbUrl, thumbWidth, thumbHeight, description, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultDocumentImpl(
data class InlineQueryResultDocumentImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(documentUrlField)
@ -31,13 +62,18 @@ data class InlineQueryResultDocumentImpl(
@SerialName(descriptionField)
override val description: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultDocument {
override val type: String = inlineQueryResultDocumentType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,18 +1,39 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultGifType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultGifCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultGifCachedImpl(id, fileId, title, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultGifCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultGifCachedImpl(id, fileId, title, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultGifCachedImpl(
data class InlineQueryResultGifCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(gifFileIdField)
@ -20,13 +41,18 @@ data class InlineQueryResultGifCachedImpl(
@SerialName(titleField)
override val title: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultGifCached {
override val type: String = inlineQueryResultGifType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultGifType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -11,8 +13,37 @@ import dev.inmo.tgbotapi.utils.MimeType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultGifImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
thumbMimeType: MimeType? = null,
width: Int? = null,
height: Int? = null,
duration: Int? = null,
title: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultGifImpl(id, url, thumbUrl, thumbMimeType, width, height, duration, title, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultGifImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
thumbMimeType: MimeType? = null,
width: Int? = null,
height: Int? = null,
duration: Int? = null,
title: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultGifImpl(id, url, thumbUrl, thumbMimeType, width, height, duration, title, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultGifImpl(
data class InlineQueryResultGifImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(gifUrlField)
@ -30,15 +61,20 @@ data class InlineQueryResultGifImpl(
@SerialName(titleField)
override val title: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultGif {
override val type: String = inlineQueryResultGifType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
if (thumbMimeType != null && thumbMimeType !in telegramInlineModeGifPermittedMimeTypes) {

View File

@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.Livable
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
@ -17,10 +16,16 @@ data class InlineQueryResultLocation(
override val latitude: Double,
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(titleField)
override val title: String,
@SerialName(livePeriodField)
override val livePeriod: Int? = null,
override val livePeriod: Seconds? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(thumbUrlField)
override val thumbUrl: String? = null,
@SerialName(thumbWidthField)
@ -33,7 +38,10 @@ data class InlineQueryResultLocation(
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResult,
Locationed,
HorizontallyAccured,
Livable,
ProximityAlertable,
Headed,
TitledInlineQueryResult,
WithInputMessageContentInlineQueryResult,
ThumbedInlineQueryResult,

View File

@ -1,18 +1,39 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultMpeg4GifType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultMpeg4GifCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultMpeg4GifCachedImpl(id, fileId, title, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultMpeg4GifCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultMpeg4GifCachedImpl(id, fileId, title, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultMpeg4GifCachedImpl(
data class InlineQueryResultMpeg4GifCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(mpeg4GifFileIdField)
@ -20,13 +41,18 @@ data class InlineQueryResultMpeg4GifCachedImpl(
@SerialName(titleField)
override val title: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultMpeg4GifCached {
override val type: String = inlineQueryResultMpeg4GifType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultMpeg4GifType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -11,8 +13,37 @@ import dev.inmo.tgbotapi.utils.MimeType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultMpeg4GifImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
thumbMimeType: MimeType? = null,
width: Int? = null,
height: Int? = null,
duration: Int? = null,
title: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultMpeg4GifImpl(id, url, thumbUrl, thumbMimeType, width, height, duration, title, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultMpeg4GifImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
thumbMimeType: MimeType? = null,
width: Int? = null,
height: Int? = null,
duration: Int? = null,
title: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultMpeg4GifImpl(id, url, thumbUrl, thumbMimeType, width, height, duration, title, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultMpeg4GifImpl(
data class InlineQueryResultMpeg4GifImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(mpeg4GifUrlField)
@ -30,15 +61,20 @@ data class InlineQueryResultMpeg4GifImpl(
@SerialName(titleField)
override val title: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultMpeg4Gif {
override val type: String = inlineQueryResultMpeg4GifType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
init {
if (thumbMimeType != null && thumbMimeType !in telegramInlineModeGifPermittedMimeTypes) {

View File

@ -1,18 +1,41 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultPhotoType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultPhotoCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String? = null,
description: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultPhotoCachedImpl(id, fileId, title, description, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultPhotoCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String? = null,
description: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultPhotoCachedImpl(id, fileId, title, description, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultPhotoCachedImpl(
data class InlineQueryResultPhotoCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(photoFileIdField)
@ -22,13 +45,18 @@ data class InlineQueryResultPhotoCachedImpl(
@SerialName(descriptionField)
override val description: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultPhotoCached {
override val type: String = inlineQueryResultPhotoType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,17 +1,46 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultPhotoType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultPhotoImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
width: Int? = null,
height: Int? = null,
title: String? = null,
description: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultPhotoImpl(id, url, thumbUrl, width, height, title, description, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultPhotoImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
width: Int? = null,
height: Int? = null,
title: String? = null,
description: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultPhotoImpl(id, url, thumbUrl, width, height, title, description, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultPhotoImpl(
data class InlineQueryResultPhotoImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(photoUrlField)
@ -27,13 +56,18 @@ data class InlineQueryResultPhotoImpl(
@SerialName(descriptionField)
override val description: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultPhoto {
override val type: String = inlineQueryResultPhotoType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -22,9 +22,13 @@ data class InlineQueryResultVenue(
@SerialName(addressField)
override val address: String,
@SerialName(foursquareIdField)
override val foursquareId: String? = null,
override val foursquareId: FoursquareId? = null,
@SerialName(foursquareTypeField)
override val foursquareType: String? = null,
override val foursquareType: FoursquareType? = null,
@SerialName(googlePlaceIdField)
override val googlePlaceId: GooglePlaceId? = null,
@SerialName(googlePlaceTypeField)
override val googlePlaceType: GooglePlaceType? = null,
@SerialName(thumbUrlField)
override val thumbUrl: String? = null,
@SerialName(thumbWidthField)

View File

@ -1,18 +1,41 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultVideoType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultVideoCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String,
description: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVideoCachedImpl(id, fileId, title, description, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultVideoCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String,
description: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVideoCachedImpl(id, fileId, title, description, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultVideoCachedImpl(
data class InlineQueryResultVideoCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(videoFileIdField)
@ -22,13 +45,18 @@ data class InlineQueryResultVideoCachedImpl(
@SerialName(descriptionField)
override val description: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVideoCached {
override val type: String = inlineQueryResultVideoType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,9 +1,11 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultVideoType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -12,8 +14,39 @@ import dev.inmo.tgbotapi.utils.MimeType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultVideoImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
mimeType: MimeType,
title: String,
width: Int? = null,
height: Int? = null,
duration: Int? = null,
description: String? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVideoImpl(id, url, thumbUrl, mimeType, title, width, height, duration, description, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultVideoImpl(
id: InlineQueryIdentifier,
url: String,
thumbUrl: String,
mimeType: MimeType,
title: String,
width: Int? = null,
height: Int? = null,
duration: Int? = null,
description: String? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVideoImpl(id, url, thumbUrl, mimeType, title, width, height, duration, description, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultVideoImpl(
data class InlineQueryResultVideoImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(videoUrlField)
@ -33,13 +66,18 @@ data class InlineQueryResultVideoImpl(
@SerialName(descriptionField)
override val description: String? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVideo {
override val type: String = inlineQueryResultVideoType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,18 +1,39 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.FileId
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.inlineQueryResultVoiceType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultVoiceCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVoiceCachedImpl(id, fileId, title, text, parseMode, null, replyMarkup, inputMessageContent)
fun InlineQueryResultVoiceCachedImpl(
id: InlineQueryIdentifier,
fileId: FileId,
title: String,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVoiceCachedImpl(id, fileId, title, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultVoiceCachedImpl(
data class InlineQueryResultVoiceCachedImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(voiceFileIdField)
@ -20,13 +41,18 @@ data class InlineQueryResultVoiceCachedImpl(
@SerialName(titleField)
override val title: String,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVoiceCached {
override val type: String = inlineQueryResultVoiceType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,17 +1,50 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.*
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.inlineQueryResultVoiceType
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InlineQueryResultVoiceImpl(
id: InlineQueryIdentifier,
url: String,
title: String,
duration: Int? = null,
text: String? = null,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVoiceImpl(
id,
url,
title,
duration,
text,
parseMode,
null,
replyMarkup,
inputMessageContent
)
fun InlineQueryResultVoiceImpl(
id: InlineQueryIdentifier,
url: String,
title: String,
duration: Int? = null,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null,
inputMessageContent: InputMessageContent? = null
) = InlineQueryResultVoiceImpl(id, url, title, duration, entities.makeString(), null, entities.toRawMessageEntities(), replyMarkup, inputMessageContent)
@Serializable
data class InlineQueryResultVoiceImpl(
data class InlineQueryResultVoiceImpl internal constructor(
@SerialName(idField)
override val id: InlineQueryIdentifier,
@SerialName(voiceUrlField)
@ -21,13 +54,18 @@ data class InlineQueryResultVoiceImpl(
@SerialName(voiceDurationField)
override val duration: Int? = null,
@SerialName(captionField)
override val caption: String? = null,
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null,
@SerialName(inputMessageContentField)
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultVoice {
override val type: String = inlineQueryResultVoiceType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
}

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.WithInputMessageContentInlineQueryResult
@ -8,4 +9,9 @@ const val inlineQueryResultAudioType = "audio"
interface InlineQueryResultAudioCommon : InlineQueryResult,
CaptionedOutput,
WithInputMessageContentInlineQueryResult
TextedOutput,
WithInputMessageContentInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
const val inlineQueryResultDocumentType = "document"
@ -9,4 +10,9 @@ interface InlineQueryResultDocumentCommon : InlineQueryResult,
TitledInlineQueryResult,
DescribedInlineQueryResult,
CaptionedOutput,
WithInputMessageContentInlineQueryResult
TextedOutput,
WithInputMessageContentInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
const val inlineQueryResultGifType = "gif"
@ -8,4 +9,9 @@ const val inlineQueryResultGifType = "gif"
interface InlineQueryResultGifCommon : InlineQueryResult,
OptionallyTitledInlineQueryResult,
CaptionedOutput,
WithInputMessageContentInlineQueryResult
TextedOutput,
WithInputMessageContentInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
const val inlineQueryResultMpeg4GifType = "mpeg4_gif"
@ -8,4 +9,9 @@ const val inlineQueryResultMpeg4GifType = "mpeg4_gif"
interface InlineQueryResultMpeg4GifCommon : InlineQueryResult,
OptionallyTitledInlineQueryResult,
CaptionedOutput,
WithInputMessageContentInlineQueryResult
TextedOutput,
WithInputMessageContentInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
const val inlineQueryResultPhotoType = "photo"
@ -9,4 +10,9 @@ interface InlineQueryResultPhotoCommon : InlineQueryResult,
OptionallyTitledInlineQueryResult,
DescribedInlineQueryResult,
CaptionedOutput,
WithInputMessageContentInlineQueryResult
TextedOutput,
WithInputMessageContentInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
const val inlineQueryResultVideoType = "video"
@ -9,4 +10,9 @@ interface InlineQueryResultVideoCommon : InlineQueryResult,
TitledInlineQueryResult,
DescribedInlineQueryResult,
CaptionedOutput,
WithInputMessageContentInlineQueryResult
TextedOutput,
WithInputMessageContentInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,11 +1,17 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
const val inlineQueryResultVoiceType = "voice"
interface InlineQueryResultVoiceCommon : InlineQueryResult,
CaptionedOutput,
TextedOutput,
WithInputMessageContentInlineQueryResult,
TitledInlineQueryResult
TitledInlineQueryResult {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
}

View File

@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent
import dev.inmo.tgbotapi.CommonAbstracts.Livable
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import kotlinx.serialization.SerialName
@ -13,6 +12,12 @@ data class InputLocationMessageContent(
override val latitude: Double,
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(livePeriodField)
override val livePeriod: Int? = null
) : Locationed, Livable, InputMessageContent
override val livePeriod: Seconds? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null
) : Locationed, HorizontallyAccured, ProximityAlertable, Livable, Headed, InputMessageContent

View File

@ -1,21 +1,47 @@
package dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.types.DisableWebPagePreview
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.disableWebPagePreviewField
import dev.inmo.tgbotapi.types.messageTextField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Represents the [InputMessageContent] of a text message to be sent as the result of an inline query.
*/
fun InputTextMessageContent(
text: String,
parseMode: ParseMode? = null,
disableWebPagePreview: Boolean? = null
) = InputTextMessageContent(text, parseMode, null, disableWebPagePreview)
/**
* Represents the [InputMessageContent] of a text message to be sent as the result of an inline query.
*/
fun InputTextMessageContent(
entities: List<TextSource>,
disableWebPagePreview: Boolean? = null
) = InputTextMessageContent(entities.makeString(), null, entities.toRawMessageEntities(), disableWebPagePreview)
@Serializable
data class InputTextMessageContent(
data class InputTextMessageContent internal constructor(
@SerialName(messageTextField)
override val caption: String,
override val text: String,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(entitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
@SerialName(disableWebPagePreviewField)
override val disableWebPagePreview: Boolean? = null
) : CaptionedOutput, DisableWebPagePreview, InputMessageContent
) : CaptionedOutput, TextedOutput, DisableWebPagePreview, InputMessageContent {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text) ?.justTextSources()
}
}

View File

@ -18,7 +18,11 @@ data class InputVenueMessageContent(
@SerialName(addressField)
override val address: String,
@SerialName(foursquareIdField)
override val foursquareId: String? = null,
override val foursquareId: FoursquareId? = null,
@SerialName(foursquareTypeField)
override val foursquareType: String? = null
override val foursquareType: FoursquareType? = null,
@SerialName(googlePlaceIdField)
override val googlePlaceId: GooglePlaceId? = null,
@SerialName(googlePlaceTypeField)
override val googlePlaceType: GooglePlaceType? = null
) : Locationed, CommonVenueData, InputMessageContent

View File

@ -1,7 +1,9 @@
package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
import dev.inmo.tgbotapi.types.InlineQueryIdentifier
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.location.Location
data class LocationInlineQuery(
override val id: InlineQueryIdentifier,

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.location.Location
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@ -1,25 +1,56 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.InputFile
import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.mediaField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun InputMediaAnimation(
file: InputFile,
text: String? = null,
parseMode: ParseMode? = null,
width: Int? = null,
height: Int? = null,
duration: Long? = null,
thumb: InputFile? = null
) = InputMediaAnimation(file, text, parseMode, null, width, height, duration, thumb)
fun InputMediaAnimation(
file: InputFile,
entities: List<TextSource>,
width: Int? = null,
height: Int? = null,
duration: Long? = null,
thumb: InputFile? = null
) = InputMediaAnimation(file, entities.makeString(), null, entities.toRawMessageEntities(), width, height, duration, thumb)
@Serializable
data class InputMediaAnimation(
data class InputMediaAnimation internal constructor(
override val file: InputFile,
override val caption: String? = null,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
override val width: Int? = null,
override val height: Int? = null,
override val duration: Long? = null,
override val thumb: InputFile? = null
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, CaptionedOutput {
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, TextedOutput, CaptionedOutput {
override val type: String = "animation"
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
@SerialName(mediaField)
override val media: String

View File

@ -1,30 +1,58 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.Performerable
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.InputFile
import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.files.AudioFile
import dev.inmo.tgbotapi.types.files.PhotoSize
import dev.inmo.tgbotapi.types.mediaField
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
import kotlinx.serialization.*
internal const val audioInputMediaType = "audio"
fun InputMediaAudio(
file: InputFile,
entities: List<TextSource>,
duration: Long? = null,
performer: String? = null,
title: String? = null,
thumb: InputFile? = null
) = InputMediaAudio(
file, entities.makeString(), null, entities.toRawMessageEntities(), duration, performer, title, thumb
)
fun InputMediaAudio(
file: InputFile,
text: String? = null,
parseMode: ParseMode? = null,
duration: Long? = null,
performer: String? = null,
title: String? = null,
thumb: InputFile? = null
) = InputMediaAudio(
file, text, parseMode, null, duration, performer, title, thumb
)
@Serializable
data class InputMediaAudio(
data class InputMediaAudio internal constructor(
override val file: InputFile,
override val caption: String? = null,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
override val duration: Long? = null,
override val performer: String? = null,
override val title: String? = null,
override val thumb: InputFile? = null
) : InputMedia, AudioMediaGroupMemberInputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, CaptionedOutput, Performerable {
) : InputMedia, AudioMediaGroupMemberInputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, Performerable {
override val type: String = audioInputMediaType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)

View File

@ -1,24 +1,58 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.mediaField
import kotlinx.serialization.*
internal const val documentInputMediaType = "document"
fun InputMediaDocument(
file: InputFile,
caption: String? = null,
parseMode: ParseMode? = null,
thumb: InputFile? = null,
disableContentTypeDetection: Boolean? = null
) = InputMediaDocument(file, caption, parseMode, null, thumb, disableContentTypeDetection)
fun InputMediaDocument(
file: InputFile,
entities: List<TextSource>,
thumb: InputFile? = null,
disableContentTypeDetection: Boolean? = null
) = InputMediaDocument(file, entities.makeString(), null, entities.toRawMessageEntities(), thumb, disableContentTypeDetection)
/**
* Represents a general file to be sent. See https://core.telegram.org/bots/api#inputmediadocument
*
* @param disableContentTypeDetection Disables automatic server-side content type detection for files uploaded using
* multipart/form-data. Always used by Telegram system as true, if the document is sent as part of an album.
*
* @see InputFile
* @see MultipartFile
* @see FileId
*/
@Serializable
data class InputMediaDocument(
data class InputMediaDocument internal constructor(
override val file: InputFile,
override val caption: String? = null,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
override val thumb: InputFile? = null
) : InputMedia, DocumentMediaGroupMemberInputMedia, ThumbedInputMedia, CaptionedOutput {
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
override val thumb: InputFile? = null,
@SerialName(disableContentTypeDetectionField)
val disableContentTypeDetection: Boolean? = null
) : InputMedia, DocumentMediaGroupMemberInputMedia, ThumbedInputMedia {
override val type: String = documentInputMediaType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)

View File

@ -1,24 +1,42 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.InputFile
import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.files.PhotoSize
import dev.inmo.tgbotapi.types.mediaField
import kotlinx.serialization.*
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
internal const val photoInputMediaType = "photo"
fun InputMediaPhoto(
file: InputFile,
text: String? = null,
parseMode: ParseMode? = null
) = InputMediaPhoto(file, text, parseMode, null)
fun InputMediaPhoto(
file: InputFile,
entities: List<TextSource>
) = InputMediaPhoto(file, entities.makeString(), null, entities.toRawMessageEntities())
@Serializable
data class InputMediaPhoto(
data class InputMediaPhoto internal constructor(
override val file: InputFile,
override val caption: String? = null,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null
) : InputMedia, VisualMediaGroupMemberInputMedia {
override val type: String = photoInputMediaType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)

View File

@ -1,26 +1,53 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.InputFile
import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.MessageEntity.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
import dev.inmo.tgbotapi.types.mediaField
import kotlinx.serialization.*
import kotlinx.serialization.json.JsonElement
internal const val videoInputMediaType = "video"
fun InputMediaVideo(
file: InputFile,
text: String? = null,
parseMode: ParseMode? = null,
width: Int? = null,
height: Int? = null,
duration: Long? = null,
thumb: InputFile? = null
) = InputMediaVideo(file, text, parseMode, null, width, height, duration, thumb)
fun InputMediaVideo(
file: InputFile,
entities: List<TextSource>,
width: Int? = null,
height: Int? = null,
duration: Long? = null,
thumb: InputFile? = null
) = InputMediaVideo(file, entities.makeString(), null, entities.toRawMessageEntities(), width, height, duration, thumb)
@Serializable
data class InputMediaVideo(
data class InputMediaVideo internal constructor (
override val file: InputFile,
override val caption: String? = null,
@SerialName(captionField)
override val text: String? = null,
@SerialName(parseModeField)
override val parseMode: ParseMode? = null,
@SerialName(captionEntitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
override val width: Int? = null,
override val height: Int? = null,
override val duration: Long? = null,
override val thumb: InputFile? = null
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, VisualMediaGroupMemberInputMedia {
override val type: String = videoInputMediaType
override val entities: List<TextSource>? by lazy {
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
}
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)

View File

@ -1,8 +1,9 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.json.Json
internal val argumentsFormatter by lazy {
Json {
@ -15,7 +16,10 @@ internal fun <T> T.buildArguments(withSerializer: SerializationStrategy<T>) = ar
)
@Serializable(MediaGroupMemberInputMediaSerializer::class)
interface MediaGroupMemberInputMedia : InputMedia, CaptionedOutput {
interface MediaGroupMemberInputMedia : InputMedia, CaptionedOutput, TextedOutput {
@Deprecated("Will be removed in next major release")
override val caption: String?
get() = text
fun serialize(format: StringFormat): String
}

View File

@ -1,20 +1,7 @@
package dev.inmo.tgbotapi.types.InputMedia
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.types.thumbField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
interface ThumbedInputMedia : InputMedia {
val thumb: InputFile?
@Serializable
@SerialName(thumbField)
@Deprecated("Will be removed due to useless state")
val thumbMedia: String?
get() = thumb ?.let {
when (it) {
is FileId -> it.fileId
is MultipartFile -> it.fileId.toInputMediaFileAttachmentName()
}
}
}

View File

@ -1,13 +0,0 @@
package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Location(
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(latitudeField)
override val latitude: Double
) : Locationed

View File

@ -1,10 +1,10 @@
package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.MultilevelTextSource
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.utils.shiftSourcesToTheLeft
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.shiftSourcesToTheLeft
import kotlinx.serialization.Serializable
@Serializable
@ -17,26 +17,29 @@ internal data class RawMessageEntity(
val language: String? = null
)
internal fun RawMessageEntity.asTextParts(source: String, subParts: List<TextPart>): List<TextPart> {
val sourceSubstring = source.substring(offset, offset + length)
internal fun RawMessageEntity.asTextParts(
source: String,
subParts: List<TextPart>
): List<TextPart> {
val sourceSubstring: String = source.substring(offset, offset + length)
val range = offset until (offset + length)
val shiftedSubParts = subParts.shiftSourcesToTheLeft(offset)
val shiftedSubSources = sourceSubstring.fullListOfSubSource(subParts.shiftSourcesToTheLeft(offset)).justTextSources()
return when (type) {
"mention" -> MentionTextSource(sourceSubstring, shiftedSubParts)
"hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubParts)
"cashtag" -> CashTagTextSource(sourceSubstring, shiftedSubParts)
"bot_command" -> BotCommandTextSource(sourceSubstring, shiftedSubParts)
"mention" -> MentionTextSource(sourceSubstring, shiftedSubSources)
"hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubSources)
"cashtag" -> CashTagTextSource(sourceSubstring, shiftedSubSources)
"bot_command" -> BotCommandTextSource(sourceSubstring)
"url" -> URLTextSource(sourceSubstring)
"email" -> EMailTextSource(sourceSubstring, shiftedSubParts)
"phone_number" -> PhoneNumberTextSource(sourceSubstring, shiftedSubParts)
"bold" -> BoldTextSource(sourceSubstring, shiftedSubParts)
"italic" -> ItalicTextSource(sourceSubstring, shiftedSubParts)
"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"), shiftedSubParts)
"underline" -> UnderlineTextSource(sourceSubstring, shiftedSubParts)
"strikethrough" -> StrikethroughTextSource(sourceSubstring, shiftedSubParts)
"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)
@ -48,7 +51,7 @@ internal fun RawMessageEntity.asTextParts(source: String, subParts: List<TextPar
}
}
internal fun createTextPart(from: String, entities: RawMessageEntities): List<TextPart> {
internal fun createTextPart(originalFullString: String, entities: RawMessageEntities): List<TextPart> {
val mutableEntities = entities.toMutableList()
mutableEntities.sortBy { it.offset }
val resultList = mutableListOf<TextPart>()
@ -74,8 +77,8 @@ internal fun createTextPart(from: String, entities: RawMessageEntities): List<Te
resultList.addAll(
currentFirst.asTextParts(
from,
createTextPart(from, subEntities)
originalFullString,
createTextPart(originalFullString, subEntities)
)
)
}
@ -83,28 +86,60 @@ internal fun createTextPart(from: String, entities: RawMessageEntities): List<Te
return resultList
}
internal fun List<TextPart>.asRawMessageEntities() = mapNotNull {
val source = it.source
internal fun TextPart.asRawMessageEntities(): List<RawMessageEntity> {
val source = source
val length = range.last - range.first + 1
return listOfNotNull(
when (source) {
is MentionTextSource -> RawMessageEntity("mention", it.range.first, it.range.last - it.range.first)
is HashTagTextSource -> RawMessageEntity("hashtag", it.range.first, it.range.last - it.range.first)
is CashTagTextSource -> RawMessageEntity("cashtag", it.range.first, it.range.last - it.range.first)
is BotCommandTextSource -> RawMessageEntity("bot_command", it.range.first, it.range.last - it.range.first)
is URLTextSource -> RawMessageEntity("url", it.range.first, it.range.last - it.range.first)
is EMailTextSource -> RawMessageEntity("email", it.range.first, it.range.last - it.range.first)
is PhoneNumberTextSource -> RawMessageEntity("phone_number", it.range.first, it.range.last - it.range.first)
is BoldTextSource -> RawMessageEntity("bold", it.range.first, it.range.last - it.range.first)
is ItalicTextSource -> RawMessageEntity("italic", it.range.first, it.range.last - it.range.first)
is CodeTextSource -> RawMessageEntity("code", it.range.first, it.range.last - it.range.first)
is PreTextSource -> RawMessageEntity("pre", it.range.first, it.range.last - it.range.first, language = source.language)
is TextLinkTextSource -> RawMessageEntity("text_link", it.range.first, it.range.last - it.range.first, source.url)
is TextMentionTextSource -> RawMessageEntity("text_mention", it.range.first, it.range.last - it.range.first, user = source.user)
is UnderlineTextSource -> RawMessageEntity("underline", it.range.first, it.range.last - it.range.first)
is StrikethroughTextSource -> RawMessageEntity("strikethrough", it.range.first, it.range.last - it.range.first)
is MentionTextSource -> RawMessageEntity("mention", range.first, length)
is HashTagTextSource -> RawMessageEntity("hashtag", range.first, length)
is CashTagTextSource -> RawMessageEntity("cashtag", range.first, length)
is BotCommandTextSource -> RawMessageEntity("bot_command", range.first, length)
is URLTextSource -> RawMessageEntity("url", range.first, length)
is EMailTextSource -> RawMessageEntity("email", range.first, length)
is PhoneNumberTextSource -> RawMessageEntity("phone_number", range.first, length)
is BoldTextSource -> RawMessageEntity("bold", range.first, length)
is ItalicTextSource -> RawMessageEntity("italic", range.first, length)
is CodeTextSource -> RawMessageEntity("code", range.first, length)
is PreTextSource -> RawMessageEntity("pre", range.first, length, language = source.language)
is TextLinkTextSource -> RawMessageEntity("text_link", range.first, length, source.url)
is TextMentionTextSource -> RawMessageEntity("text_mention", range.first, length, user = source.user)
is UnderlineTextSource -> RawMessageEntity("underline", range.first, length)
is StrikethroughTextSource -> RawMessageEntity("strikethrough", range.first, length)
else -> null
}
) + if (source is MultilevelTextSource) {
source.textParts(range.first).asRawMessageEntities()
} else {
emptyList()
}
}
internal fun RawMessageEntities.asTextParts(sourceString: String): List<TextPart> = createTextPart(sourceString, this)
internal fun List<TextPart>.asRawMessageEntities(): List<RawMessageEntity> = flatMap { it.asRawMessageEntities() }
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 String.removeLeading(word: String) = if (startsWith(word)){
substring(word.length)
} else {
this
}
internal fun List<TextSource>.toRawMessageEntities(): List<RawMessageEntity> = toTextParts().asRawMessageEntities()
internal fun RawMessageEntities.asTextParts(sourceString: String): List<TextPart> = sourceString.fullListOfSubSource(
createTextPart(sourceString, this)
)
internal typealias RawMessageEntities = List<RawMessageEntity>

View File

@ -1,15 +1,26 @@
package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.MultilevelTextSource
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.boldMarkdown
import dev.inmo.tgbotapi.utils.internal.boldMarkdownV2
class BoldTextSource(
/**
* @see bold
*/
data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String,
textParts: List<TextPart>
override val textSources: List<TextSource>
) : MultilevelTextSource {
override val textParts: List<TextPart> by lazy { source.fullListOfSubSource(textParts) }
override val asMarkdownSource: String by lazy { source.boldMarkdown() }
override val asMarkdownV2Source: String by lazy { boldMarkdownV2() }
override val asHtmlSource: String by lazy { boldHTML() }
}
@Suppress("NOTHING_TO_INLINE")
inline fun bold(parts: List<TextSource>) = BoldTextSource(parts.makeString(), parts)
@Suppress("NOTHING_TO_INLINE")
inline fun bold(vararg parts: TextSource) = bold(parts.toList())
@Suppress("NOTHING_TO_INLINE")
inline fun bold(text: String) = bold(regular(text))

View File

@ -1,25 +1,30 @@
package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.MultilevelTextSource
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.commandMarkdown
import dev.inmo.tgbotapi.utils.internal.commandMarkdownV2
private val commandRegex = Regex("[/!][^@\\s]*")
class BotCommandTextSource(
override val source: String,
textParts: List<TextPart>
) : MultilevelTextSource {
/**
* @see botCommand
*/
data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
override val source: String
) : TextSource {
val command: String by lazy {
commandRegex.find(source) ?.value ?.substring(1) ?: source.substring(1)// skip first symbol like "/" or "!"
}
override val textParts: List<TextPart> by lazy {
command.fullListOfSubSource(
textParts.shiftSourcesToTheLeft(1)
)
}
override val asMarkdownSource: String by lazy { source.commandMarkdown() }
override val asMarkdownV2Source: String by lazy { commandMarkdownV2() }
override val asHtmlSource: String by lazy { commandHTML() }
override val asMarkdownV2Source: String by lazy { source.commandMarkdownV2() }
override val asHtmlSource: String by lazy { source.commandHTML() }
}
/**
* @param command Without leading "/"
*/
@Suppress("NOTHING_TO_INLINE")
inline fun botCommand(command: String) = BotCommandTextSource("/$command")

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