mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-29 13:38:43 +00:00
commit
43a36072f1
35
CHANGELOG.md
35
CHANGELOG.md
@ -1,5 +1,40 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 0.23.0 TelegramBotAPI 4.6
|
||||||
|
|
||||||
|
* `Poll` now is sealed class
|
||||||
|
* `RegularPoll` type was added to represent polls with type `regular`
|
||||||
|
* `QuizPoll` type was added to represent polls with type `quiz`
|
||||||
|
* `UnknownPollType` type was added to represent polls which are unknown in current version
|
||||||
|
* `AnonymousPollOption` was renamed to `SimplePollOption`
|
||||||
|
* `SendPoll` was rewritten as sealed class
|
||||||
|
* `SendRegularPoll` was created and represent `sendPoll` method with type `regular`
|
||||||
|
* `SendQuizPoll` was created and represent `sendPoll` method with type `quiz`
|
||||||
|
* `Poll#createRequest` extension was added
|
||||||
|
* `PollAnswerUpdate` type of update was added
|
||||||
|
* `PollAnswer` type was added
|
||||||
|
* `UpdatesFilter` now support work with `PollAnswerUpdate`
|
||||||
|
* `language` field in PreTextSource now correctly passed from telegram MessageEntities
|
||||||
|
* `KeyboardButton` now is sealed class
|
||||||
|
* Fixed problem of incorrect representation of this class (any type of request can be created separately)
|
||||||
|
* Added new types of `KeyboardButton`:
|
||||||
|
* `UnknownKeyboardButton`
|
||||||
|
* `SimpleKeyboardButton`
|
||||||
|
* `RequestContactKeyboardButton`
|
||||||
|
* `RequestLocationKeyboardButton`
|
||||||
|
* `RequestPollKeyboardButton`
|
||||||
|
* Added new type `KeyboardButtonPollType`:
|
||||||
|
* `UnknownKeyboardButtonPollType`
|
||||||
|
* `RegularKeyboardButtonPollType`
|
||||||
|
* `QuizKeyboardButtonPollType`
|
||||||
|
* `User` now is sealed class
|
||||||
|
* `CommonUser` was added as representation of default `User`
|
||||||
|
* `Bot` was added as representation of bot user (it is sealed class)
|
||||||
|
* `ExtendedBot` with additional info
|
||||||
|
* `CommonBot` with simple info
|
||||||
|
* `GetMe` now return `ExtendedBot` object
|
||||||
|
* Now extension `javaLocale` is extension for `CommonUser`
|
||||||
|
|
||||||
## 0.22.0
|
## 0.22.0
|
||||||
|
|
||||||
* **`KtorCallFactory` must return `HttpStatement` instead of `HttpClientCall`**
|
* **`KtorCallFactory` must return `HttpStatement` instead of `HttpClientCall`**
|
||||||
|
@ -10,7 +10,7 @@ moments are describing by official [Telegram Bot API](https://core.telegram.org/
|
|||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
This version compatible with [31th of December 2019 update of TelegramBotAPI (version 4.5)](https://core.telegram.org/bots/api#december-31-2019).
|
This version compatible with [23th of January 2020 update of TelegramBotAPI (version 4.6)](https://core.telegram.org/bots/api#january-23-2020).
|
||||||
There is Telegram Passport API exception of implemented functionality, which was presented in
|
There is Telegram Passport API exception of implemented functionality, which was presented in
|
||||||
[August 2018 update of TelegramBotAPI](https://core.telegram.org/bots/api#august-27-2018) update. It will be implemented
|
[August 2018 update of TelegramBotAPI](https://core.telegram.org/bots/api#august-27-2018) update. It will be implemented
|
||||||
as soon as possible. All APIs that are not included are presented
|
as soon as possible. All APIs that are not included are presented
|
||||||
@ -96,10 +96,9 @@ val requestsExecutor: RequestsExecutor = ...
|
|||||||
requestsExecutor.execute(GetMe())
|
requestsExecutor.execute(GetMe())
|
||||||
```
|
```
|
||||||
|
|
||||||
The result type of [GetMe](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/GetMe.kt) request is
|
The result type of [GetMe](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/GetMe.kt)
|
||||||
[User](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/User.kt). In fact, in this result must contain
|
request is
|
||||||
`isBot` equal to `true` always.
|
[ExtendedBot](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/User.kt).
|
||||||
|
|
||||||
|
|
||||||
### RequestsExecutor
|
### RequestsExecutor
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ plugins {
|
|||||||
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
|
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
project.version = "0.22.2"
|
project.version = "0.23.0"
|
||||||
project.group = "com.github.insanusmokrassar"
|
project.group = "com.github.insanusmokrassar"
|
||||||
|
|
||||||
apply from: "publish.gradle"
|
apply from: "publish.gradle"
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.requests
|
package com.github.insanusmokrassar.TelegramBotAPI.requests
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.SimpleRequest
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.SimpleRequest
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.User
|
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class GetMe : SimpleRequest<User> {
|
class GetMe : SimpleRequest<ExtendedBot> {
|
||||||
override fun method(): String = "getMe"
|
override fun method(): String = "getMe"
|
||||||
override val resultDeserializer: DeserializationStrategy<User>
|
override val resultDeserializer: DeserializationStrategy<ExtendedBot>
|
||||||
get() = User.serializer()
|
get() = ExtendedBot.serializer()
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
@ -1,51 +0,0 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.requests.send
|
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.abstracts.ReplyingMarkupSendMessageRequest
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.abstracts.SendMessageRequest
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.PollContent
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
|
|
||||||
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PollContent>>
|
|
||||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SendPoll(
|
|
||||||
@SerialName(chatIdField)
|
|
||||||
override val chatId: ChatIdentifier,
|
|
||||||
@SerialName(questionField)
|
|
||||||
val question: String,
|
|
||||||
@SerialName(optionsField)
|
|
||||||
val options: List<String>,
|
|
||||||
@SerialName(disableNotificationField)
|
|
||||||
override val disableNotification: Boolean = false,
|
|
||||||
@SerialName(replyToMessageIdField)
|
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
|
||||||
) : SendMessageRequest<ContentMessage<PollContent>>,
|
|
||||||
ReplyingMarkupSendMessageRequest<ContentMessage<PollContent>> {
|
|
||||||
|
|
||||||
init {
|
|
||||||
if (question.length !in pollQuestionTextLength) {
|
|
||||||
throw IllegalArgumentException("The length of questions for polls must be in $pollQuestionTextLength range, but was ${question.length}")
|
|
||||||
}
|
|
||||||
options.forEach {
|
|
||||||
if (it.length !in pollOptionTextLength) {
|
|
||||||
throw IllegalArgumentException("The length of question option text for polls must be in $pollOptionTextLength range, but was ${it.length}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (options.size !in pollOptionsLimit) {
|
|
||||||
throw IllegalArgumentException("The amount of question options for polls must be in $pollOptionsLimit range, but was ${options.size}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = "sendPoll"
|
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<PollContent>>
|
|
||||||
get() = commonResultDeserializer
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
}
|
|
@ -0,0 +1,185 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.requests.send.polls
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.abstracts.ReplyingMarkupSendMessageRequest
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.abstracts.SendMessageRequest
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.PollContent
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PollContent>> = TelegramBotAPIMessageDeserializationStrategyClass()
|
||||||
|
|
||||||
|
private fun checkPollInfo(
|
||||||
|
question: String,
|
||||||
|
options: List<String>
|
||||||
|
) {
|
||||||
|
if (question.length !in pollQuestionTextLength) {
|
||||||
|
throw IllegalArgumentException("The length of questions for polls must be in $pollQuestionTextLength range, but was ${question.length}")
|
||||||
|
}
|
||||||
|
options.forEach {
|
||||||
|
if (it.length !in pollOptionTextLength) {
|
||||||
|
throw IllegalArgumentException("The length of question option text for polls must be in $pollOptionTextLength range, but was ${it.length}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.size !in pollOptionsLimit) {
|
||||||
|
throw IllegalArgumentException("The amount of question options for polls must be in $pollOptionsLimit range, but was ${options.size}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SendPoll(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
question: String,
|
||||||
|
options: List<String>,
|
||||||
|
isAnonymous: Boolean = true,
|
||||||
|
isClosed: Boolean = false,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = SendRegularPoll(
|
||||||
|
chatId,
|
||||||
|
question,
|
||||||
|
options,
|
||||||
|
isAnonymous,
|
||||||
|
isClosed,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
replyToMessageId = replyToMessageId,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return [SendPoll] in case when all is right. It can return [SendRegularPoll] for [QuizPoll] in case if
|
||||||
|
* [QuizPoll.correctOptionId] equal to null
|
||||||
|
*/
|
||||||
|
fun Poll.createRequest(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = when (this) {
|
||||||
|
is RegularPoll -> SendRegularPoll(
|
||||||
|
chatId,
|
||||||
|
question,
|
||||||
|
options.map { it.text },
|
||||||
|
isAnonymous,
|
||||||
|
isClosed,
|
||||||
|
allowMultipleAnswers,
|
||||||
|
disableNotification,
|
||||||
|
replyToMessageId,
|
||||||
|
replyMarkup
|
||||||
|
)
|
||||||
|
is QuizPoll -> correctOptionId ?.let { correctOptionId ->
|
||||||
|
SendQuizPoll(
|
||||||
|
chatId,
|
||||||
|
question,
|
||||||
|
options.map { it.text },
|
||||||
|
correctOptionId,
|
||||||
|
isAnonymous,
|
||||||
|
isClosed,
|
||||||
|
disableNotification,
|
||||||
|
replyToMessageId,
|
||||||
|
replyMarkup
|
||||||
|
)
|
||||||
|
} ?: SendRegularPoll(
|
||||||
|
chatId,
|
||||||
|
question,
|
||||||
|
options.map { it.text },
|
||||||
|
isAnonymous,
|
||||||
|
isClosed,
|
||||||
|
false,
|
||||||
|
disableNotification,
|
||||||
|
replyToMessageId,
|
||||||
|
replyMarkup
|
||||||
|
)
|
||||||
|
is UnknownPollType -> SendRegularPoll(
|
||||||
|
chatId,
|
||||||
|
question,
|
||||||
|
options.map { it.text },
|
||||||
|
isAnonymous,
|
||||||
|
isClosed,
|
||||||
|
false,
|
||||||
|
disableNotification,
|
||||||
|
replyToMessageId,
|
||||||
|
replyMarkup
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class SendPoll : SendMessageRequest<ContentMessage<PollContent>>,
|
||||||
|
ReplyingMarkupSendMessageRequest<ContentMessage<PollContent>> {
|
||||||
|
abstract val question: String
|
||||||
|
abstract val options: List<String>
|
||||||
|
abstract val isAnonymous: Boolean
|
||||||
|
abstract val isClosed: Boolean
|
||||||
|
abstract val type: String
|
||||||
|
|
||||||
|
override fun method(): String = "sendPoll"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<PollContent>>
|
||||||
|
get() = commonResultDeserializer
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SendRegularPoll(
|
||||||
|
@SerialName(chatIdField)
|
||||||
|
override val chatId: ChatIdentifier,
|
||||||
|
@SerialName(questionField)
|
||||||
|
override val question: String,
|
||||||
|
@SerialName(optionsField)
|
||||||
|
override val options: List<String>,
|
||||||
|
@SerialName(isAnonymousField)
|
||||||
|
override val isAnonymous: Boolean = true,
|
||||||
|
@SerialName(isClosedField)
|
||||||
|
override val isClosed: Boolean = false,
|
||||||
|
@SerialName(allowsMultipleAnswersField)
|
||||||
|
val allowMultipleAnswers: Boolean = false,
|
||||||
|
@SerialName(disableNotificationField)
|
||||||
|
override val disableNotification: Boolean = false,
|
||||||
|
@SerialName(replyToMessageIdField)
|
||||||
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
|
@SerialName(replyMarkupField)
|
||||||
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
|
) : SendPoll() {
|
||||||
|
override val type: String = regularPollType
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
init {
|
||||||
|
checkPollInfo(question, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SendQuizPoll(
|
||||||
|
@SerialName(chatIdField)
|
||||||
|
override val chatId: ChatIdentifier,
|
||||||
|
@SerialName(questionField)
|
||||||
|
override val question: String,
|
||||||
|
@SerialName(optionsField)
|
||||||
|
override val options: List<String>,
|
||||||
|
@SerialName(correctOptionIdField)
|
||||||
|
val correctOptionId: Int,
|
||||||
|
@SerialName(isAnonymousField)
|
||||||
|
override val isAnonymous: Boolean = true,
|
||||||
|
@SerialName(isClosedField)
|
||||||
|
override val isClosed: Boolean = false,
|
||||||
|
@SerialName(disableNotificationField)
|
||||||
|
override val disableNotification: Boolean = false,
|
||||||
|
@SerialName(replyToMessageIdField)
|
||||||
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
|
@SerialName(replyMarkupField)
|
||||||
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
|
) : SendPoll() {
|
||||||
|
override val type: String = quizPollType
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
init {
|
||||||
|
checkPollInfo(question, options)
|
||||||
|
val correctOptionIdRange = 0 .. options.size
|
||||||
|
if (correctOptionId !in correctOptionIdRange) {
|
||||||
|
throw IllegalArgumentException("Correct option id must be in range of $correctOptionIdRange, but actual " +
|
||||||
|
"value is $correctOptionId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -57,6 +57,9 @@ const val isBotField = "is_bot"
|
|||||||
const val firstNameField = "first_name"
|
const val firstNameField = "first_name"
|
||||||
const val lastNameField = "last_name"
|
const val lastNameField = "last_name"
|
||||||
const val languageCodeField = "language_code"
|
const val languageCodeField = "language_code"
|
||||||
|
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 textEntitiesField = "text_entities"
|
||||||
const val stickerSetNameField = "set_name"
|
const val stickerSetNameField = "set_name"
|
||||||
const val stickerSetNameFullField = "sticker_set_name"
|
const val stickerSetNameFullField = "sticker_set_name"
|
||||||
@ -90,6 +93,10 @@ const val lastErrorDateField = "last_error_date"
|
|||||||
const val lastErrorMessageField = "last_error_message"
|
const val lastErrorMessageField = "last_error_message"
|
||||||
const val votesCountField = "voter_count"
|
const val votesCountField = "voter_count"
|
||||||
const val isClosedField = "is_closed"
|
const val isClosedField = "is_closed"
|
||||||
|
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 loginUrlField = "login_url"
|
const val loginUrlField = "login_url"
|
||||||
const val forwardTextField = "forward_text"
|
const val forwardTextField = "forward_text"
|
||||||
const val botUsernameField = "bot_username"
|
const val botUsernameField = "bot_username"
|
||||||
@ -99,6 +106,11 @@ const val isAnimatedField = "is_animated"
|
|||||||
const val inviteLinkField = "invite_link"
|
const val inviteLinkField = "invite_link"
|
||||||
const val pinnedMessageField = "pinned_message"
|
const val pinnedMessageField = "pinned_message"
|
||||||
const val customTitleField = "custom_title"
|
const val customTitleField = "custom_title"
|
||||||
|
const val optionIdsField = "option_ids"
|
||||||
|
|
||||||
|
const val requestContactField = "request_contact"
|
||||||
|
const val requestLocationField = "request_location"
|
||||||
|
const val requestPollField = "request_poll"
|
||||||
|
|
||||||
|
|
||||||
const val requestWriteAccessField = "request_write_access"
|
const val requestWriteAccessField = "request_write_access"
|
||||||
@ -173,6 +185,7 @@ const val pngStickerField = "png_sticker"
|
|||||||
const val okField = "ok"
|
const val okField = "ok"
|
||||||
const val captionField = "caption"
|
const val captionField = "caption"
|
||||||
const val idField = "id"
|
const val idField = "id"
|
||||||
|
const val pollIdField = "poll_id"
|
||||||
const val textField = "text"
|
const val textField = "text"
|
||||||
const val thumbField = "thumb"
|
const val thumbField = "thumb"
|
||||||
const val emojiField = "emoji"
|
const val emojiField = "emoji"
|
||||||
@ -273,3 +286,6 @@ const val mediaField = "media"
|
|||||||
const val disableEditMessageField = "disable_edit_message"
|
const val disableEditMessageField = "disable_edit_message"
|
||||||
const val scoreField = "score"
|
const val scoreField = "score"
|
||||||
const val forceField = "force"
|
const val forceField = "force"
|
||||||
|
|
||||||
|
const val regularPollType = "regular"
|
||||||
|
const val quizPollType = "quiz"
|
||||||
|
@ -13,7 +13,8 @@ internal data class RawMessageEntity(
|
|||||||
val offset: Int,
|
val offset: Int,
|
||||||
val length: Int,
|
val length: Int,
|
||||||
val url: String? = null,
|
val url: String? = null,
|
||||||
val user: User? = null
|
val user: User? = null,
|
||||||
|
val language: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun RawMessageEntity.asTextParts(source: String, subParts: List<TextPart>): List<TextPart> {
|
internal fun RawMessageEntity.asTextParts(source: String, subParts: List<TextPart>): List<TextPart> {
|
||||||
@ -31,7 +32,7 @@ internal fun RawMessageEntity.asTextParts(source: String, subParts: List<TextPar
|
|||||||
"bold" -> BoldTextSource(sourceSubstring, shiftedSubParts)
|
"bold" -> BoldTextSource(sourceSubstring, shiftedSubParts)
|
||||||
"italic" -> ItalicTextSource(sourceSubstring, shiftedSubParts)
|
"italic" -> ItalicTextSource(sourceSubstring, shiftedSubParts)
|
||||||
"code" -> CodeTextSource(sourceSubstring)
|
"code" -> CodeTextSource(sourceSubstring)
|
||||||
"pre" -> PreTextSource(sourceSubstring)
|
"pre" -> PreTextSource(sourceSubstring, language)
|
||||||
"text_link" -> TextLinkTextSource(sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link"))
|
"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)
|
"text_mention" -> TextMentionTextSource(sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention"), shiftedSubParts)
|
||||||
"underline" -> UnderlineTextSource(sourceSubstring, shiftedSubParts)
|
"underline" -> UnderlineTextSource(sourceSubstring, shiftedSubParts)
|
||||||
|
@ -10,6 +10,7 @@ const val UPDATE_CALLBACK_QUERY = "callback_query"
|
|||||||
const val UPDATE_SHIPPING_QUERY = "shipping_query"
|
const val UPDATE_SHIPPING_QUERY = "shipping_query"
|
||||||
const val UPDATE_PRE_CHECKOUT_QUERY = "pre_checkout_query"
|
const val UPDATE_PRE_CHECKOUT_QUERY = "pre_checkout_query"
|
||||||
const val UPDATE_POLL = "poll"
|
const val UPDATE_POLL = "poll"
|
||||||
|
const val UPDATE_POLL_ANSWER = "poll_answer"
|
||||||
|
|
||||||
val ALL_UPDATES_LIST = listOf(
|
val ALL_UPDATES_LIST = listOf(
|
||||||
UPDATE_MESSAGE,
|
UPDATE_MESSAGE,
|
||||||
@ -21,5 +22,6 @@ val ALL_UPDATES_LIST = listOf(
|
|||||||
UPDATE_CALLBACK_QUERY,
|
UPDATE_CALLBACK_QUERY,
|
||||||
UPDATE_SHIPPING_QUERY,
|
UPDATE_SHIPPING_QUERY,
|
||||||
UPDATE_PRE_CHECKOUT_QUERY,
|
UPDATE_PRE_CHECKOUT_QUERY,
|
||||||
UPDATE_POLL
|
UPDATE_POLL,
|
||||||
|
UPDATE_POLL_ANSWER
|
||||||
)
|
)
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.types
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat
|
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObjectSerializer
|
||||||
|
|
||||||
|
@Serializable(UserSerializer::class)
|
||||||
|
sealed class User : PrivateChat
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class User(
|
data class CommonUser(
|
||||||
override val id: ChatId,
|
override val id: ChatId,
|
||||||
@SerialName(isBotField)
|
|
||||||
val isBot: Boolean = false,
|
|
||||||
@SerialName(firstNameField)
|
@SerialName(firstNameField)
|
||||||
override val firstName: String,
|
override val firstName: String,
|
||||||
@SerialName(lastNameField)
|
@SerialName(lastNameField)
|
||||||
@ -17,4 +19,80 @@ data class User(
|
|||||||
override val username: Username? = null,
|
override val username: Username? = null,
|
||||||
@SerialName(languageCodeField)
|
@SerialName(languageCodeField)
|
||||||
val languageCode: String? = null
|
val languageCode: String? = null
|
||||||
) : PrivateChat
|
) : User()
|
||||||
|
|
||||||
|
@Serializable(UserSerializer::class)
|
||||||
|
sealed class Bot : User()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CommonBot(
|
||||||
|
override val id: ChatId,
|
||||||
|
@SerialName(firstNameField)
|
||||||
|
override val firstName: String,
|
||||||
|
@SerialName(lastNameField)
|
||||||
|
override val lastName: String = "",
|
||||||
|
@SerialName(usernameField)
|
||||||
|
override val username: Username? = null
|
||||||
|
) : Bot() {
|
||||||
|
@SerialName(isBotField)
|
||||||
|
private val isBot = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ExtendedBot(
|
||||||
|
override val id: ChatId,
|
||||||
|
@SerialName(firstNameField)
|
||||||
|
override val firstName: String,
|
||||||
|
@SerialName(lastNameField)
|
||||||
|
override val lastName: String = "",
|
||||||
|
@SerialName(usernameField)
|
||||||
|
override val username: Username? = null,
|
||||||
|
@SerialName(canJoinGroupsField)
|
||||||
|
val canJoinGroups: Boolean = false,
|
||||||
|
@SerialName(canReadAllGroupMessagesField)
|
||||||
|
val canReadAllGroupMessages: Boolean = false,
|
||||||
|
@SerialName(supportInlineQueriesField)
|
||||||
|
val supportsInlineQueries: Boolean = false
|
||||||
|
) : Bot() {
|
||||||
|
@SerialName(isBotField)
|
||||||
|
private val isBot = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Serializer(User::class)
|
||||||
|
internal object UserSerializer : KSerializer<User> {
|
||||||
|
override fun deserialize(decoder: Decoder): User {
|
||||||
|
val asJson = JsonObjectSerializer.deserialize(decoder)
|
||||||
|
|
||||||
|
return when {
|
||||||
|
asJson.getPrimitiveOrNull(isBotField) ?.booleanOrNull != true -> Json.nonstrict.fromJson(
|
||||||
|
CommonUser.serializer(),
|
||||||
|
asJson
|
||||||
|
)
|
||||||
|
else -> {
|
||||||
|
if ((asJson.get(canJoinGroupsField)
|
||||||
|
?: asJson.get(canReadAllGroupMessagesField)
|
||||||
|
?: asJson.get(supportInlineQueriesField)) != null
|
||||||
|
) {
|
||||||
|
Json.nonstrict.fromJson(
|
||||||
|
ExtendedBot.serializer(),
|
||||||
|
asJson
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Json.nonstrict.fromJson(
|
||||||
|
CommonBot.serializer(),
|
||||||
|
asJson
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, obj: User) {
|
||||||
|
when (obj) {
|
||||||
|
is CommonUser -> CommonUser.serializer().serialize(encoder, obj)
|
||||||
|
is CommonBot -> CommonBot.serializer().serialize(encoder, obj)
|
||||||
|
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,88 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.types.buttons
|
package com.github.insanusmokrassar.TelegramBotAPI.types.buttons
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.internal.StringDescriptor
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
@Serializable(KeyboardButtonSerializer::class)
|
||||||
|
sealed class KeyboardButton {
|
||||||
|
abstract val text: String
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class KeyboardButton(
|
data class SimpleKeyboardButton(
|
||||||
val text: String,
|
override val text: String
|
||||||
@SerialName("request_contact")
|
) : KeyboardButton()
|
||||||
val requestContact: Boolean? = null,
|
|
||||||
@SerialName("request_location")
|
@Serializable
|
||||||
val requestLocation: Boolean? = null
|
data class UnknownKeyboardButton internal constructor(
|
||||||
)
|
override val text: String,
|
||||||
|
val raw: String
|
||||||
|
) : KeyboardButton()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RequestContactKeyboardButton(
|
||||||
|
override val text: String
|
||||||
|
) : KeyboardButton() {
|
||||||
|
@SerialName(requestContactField)
|
||||||
|
val requestContact: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RequestLocationKeyboardButton(
|
||||||
|
override val text: String
|
||||||
|
) : KeyboardButton() {
|
||||||
|
@SerialName(requestLocationField)
|
||||||
|
val requestLocation: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RequestPollKeyboardButton(
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(requestPollField)
|
||||||
|
val requestPoll: KeyboardButtonPollType
|
||||||
|
) : KeyboardButton()
|
||||||
|
|
||||||
|
@Serializer(KeyboardButton::class)
|
||||||
|
internal object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
||||||
|
override fun deserialize(decoder: Decoder): KeyboardButton {
|
||||||
|
val asJson = JsonElementSerializer.deserialize(decoder)
|
||||||
|
|
||||||
|
return when {
|
||||||
|
asJson is JsonPrimitive -> SimpleKeyboardButton(asJson.content)
|
||||||
|
asJson is JsonObject && asJson.getPrimitiveOrNull(requestContactField) != null -> RequestContactKeyboardButton(
|
||||||
|
asJson.getPrimitive(textField).content
|
||||||
|
)
|
||||||
|
asJson is JsonObject && asJson.getPrimitiveOrNull(requestLocationField) != null -> RequestLocationKeyboardButton(
|
||||||
|
asJson.getPrimitive(textField).content
|
||||||
|
)
|
||||||
|
asJson is JsonObject && asJson.getObjectOrNull(requestPollField) != null -> RequestPollKeyboardButton(
|
||||||
|
asJson.getPrimitive(textField).content,
|
||||||
|
Json.nonstrict.fromJson(
|
||||||
|
KeyboardButtonPollType.serializer(),
|
||||||
|
asJson.getObject(requestPollField)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else -> UnknownKeyboardButton(
|
||||||
|
when (asJson) {
|
||||||
|
is JsonObject -> asJson.getPrimitive(textField).content
|
||||||
|
is JsonArray -> ""
|
||||||
|
is JsonPrimitive -> asJson.content
|
||||||
|
},
|
||||||
|
asJson.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, obj: KeyboardButton) {
|
||||||
|
when (obj) {
|
||||||
|
is RequestContactKeyboardButton -> RequestContactKeyboardButton.serializer().serialize(encoder, obj)
|
||||||
|
is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.serializer().serialize(encoder, obj)
|
||||||
|
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, obj)
|
||||||
|
is SimpleKeyboardButton -> encoder.encodeString(obj.text)
|
||||||
|
is UnknownKeyboardButton -> JsonElementSerializer.serialize(encoder, Json.nonstrict.parseJson(obj.raw))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types.buttons
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
@Serializable(KeyboardButtonPollTypeSerializer::class)
|
||||||
|
sealed class KeyboardButtonPollType {
|
||||||
|
abstract val type: String
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class UnknownKeyboardButtonPollType internal constructor(override val type: String): KeyboardButtonPollType()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object RegularKeyboardButtonPollType : KeyboardButtonPollType() {
|
||||||
|
override val type: String = regularPollType
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object QuizKeyboardButtonPollType : KeyboardButtonPollType() {
|
||||||
|
override val type: String = quizPollType
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializer(KeyboardButtonPollType::class)
|
||||||
|
internal object KeyboardButtonPollTypeSerializer : KSerializer<KeyboardButtonPollType> {
|
||||||
|
override fun deserialize(decoder: Decoder): KeyboardButtonPollType {
|
||||||
|
val asJson = JsonElementSerializer.deserialize(decoder)
|
||||||
|
|
||||||
|
val type = when (asJson) {
|
||||||
|
is JsonPrimitive -> asJson.content
|
||||||
|
else -> asJson.jsonObject.getPrimitive(typeField).content
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (type) {
|
||||||
|
regularPollType -> RegularKeyboardButtonPollType
|
||||||
|
quizPollType -> QuizKeyboardButtonPollType
|
||||||
|
else -> UnknownKeyboardButtonPollType(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crutch due to the fact that direct serialization of objects currently does not work perfectly
|
||||||
|
*/
|
||||||
|
override fun serialize(encoder: Encoder, obj: KeyboardButtonPollType) {
|
||||||
|
JsonObjectSerializer.serialize(
|
||||||
|
encoder,
|
||||||
|
JsonObject(
|
||||||
|
mapOf(
|
||||||
|
typeField to JsonPrimitive(obj.type)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,15 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.types.message.content
|
package com.github.insanusmokrassar.TelegramBotAPI.types.message.content
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.SendPoll
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.polls.SendPoll
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.polls.createRequest
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier
|
import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier
|
import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
|
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
|
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
|
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.Poll
|
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.Poll
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.RegularPoll
|
||||||
|
|
||||||
data class PollContent(
|
data class PollContent(
|
||||||
val poll: Poll
|
val poll: Poll
|
||||||
@ -17,10 +19,8 @@ data class PollContent(
|
|||||||
disableNotification: Boolean,
|
disableNotification: Boolean,
|
||||||
replyToMessageId: MessageIdentifier?,
|
replyToMessageId: MessageIdentifier?,
|
||||||
replyMarkup: KeyboardMarkup?
|
replyMarkup: KeyboardMarkup?
|
||||||
): Request<ContentMessage<PollContent>> = SendPoll(
|
): Request<ContentMessage<PollContent>> = poll.createRequest(
|
||||||
chatId,
|
chatId,
|
||||||
poll.question,
|
|
||||||
poll.options.map { it.text },
|
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
replyMarkup
|
replyMarkup
|
||||||
|
@ -1,17 +1,119 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.types.polls
|
package com.github.insanusmokrassar.TelegramBotAPI.types.polls
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.internal.ArrayListSerializer
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
@Serializable(PollSerializer::class)
|
||||||
|
sealed class Poll {
|
||||||
|
abstract val id: PollIdentifier
|
||||||
|
abstract val question: String
|
||||||
|
abstract val options: List<PollOption>
|
||||||
|
abstract val votesCount: Int
|
||||||
|
abstract val isClosed: Boolean
|
||||||
|
abstract val isAnonymous: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Poll(
|
data class UnknownPollType internal constructor(
|
||||||
@SerialName(idField)
|
@SerialName(idField)
|
||||||
val id: PollIdentifier,
|
override val id: PollIdentifier,
|
||||||
@SerialName(questionField)
|
@SerialName(questionField)
|
||||||
val question: String,
|
override val question: String,
|
||||||
@SerialName(optionsField)
|
@SerialName(optionsField)
|
||||||
val options: List<PollOption>,
|
override val options: List<PollOption>,
|
||||||
|
@SerialName(totalVoterCountField)
|
||||||
|
override val votesCount: Int,
|
||||||
@SerialName(isClosedField)
|
@SerialName(isClosedField)
|
||||||
val closed: Boolean = false
|
override val isClosed: Boolean = false,
|
||||||
)
|
@SerialName(isAnonymousField)
|
||||||
|
override val isAnonymous: Boolean = false,
|
||||||
|
val raw: String
|
||||||
|
) : Poll()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RegularPoll(
|
||||||
|
@SerialName(idField)
|
||||||
|
override val id: PollIdentifier,
|
||||||
|
@SerialName(questionField)
|
||||||
|
override val question: String,
|
||||||
|
@SerialName(optionsField)
|
||||||
|
override val options: List<PollOption>,
|
||||||
|
@SerialName(totalVoterCountField)
|
||||||
|
override val votesCount: Int,
|
||||||
|
@SerialName(isClosedField)
|
||||||
|
override val isClosed: Boolean = false,
|
||||||
|
@SerialName(isAnonymousField)
|
||||||
|
override val isAnonymous: Boolean = false,
|
||||||
|
@SerialName(allowsMultipleAnswersField)
|
||||||
|
val allowMultipleAnswers: Boolean = false
|
||||||
|
) : Poll()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class QuizPoll(
|
||||||
|
@SerialName(idField)
|
||||||
|
override val id: PollIdentifier,
|
||||||
|
@SerialName(questionField)
|
||||||
|
override val question: String,
|
||||||
|
@SerialName(optionsField)
|
||||||
|
override val options: List<PollOption>,
|
||||||
|
@SerialName(totalVoterCountField)
|
||||||
|
override val votesCount: Int,
|
||||||
|
/**
|
||||||
|
* Nullable due to documentation (https://core.telegram.org/bots/api#poll)
|
||||||
|
*/
|
||||||
|
@SerialName(correctOptionIdField)
|
||||||
|
val correctOptionId: Int? = null,
|
||||||
|
@SerialName(isClosedField)
|
||||||
|
override val isClosed: Boolean = false,
|
||||||
|
@SerialName(isAnonymousField)
|
||||||
|
override val isAnonymous: Boolean = false
|
||||||
|
) : Poll()
|
||||||
|
|
||||||
|
@Serializer(Poll::class)
|
||||||
|
internal object PollSerializer : KSerializer<Poll> {
|
||||||
|
private val pollOptionsSerializer = ArrayListSerializer(PollOption.serializer())
|
||||||
|
override fun deserialize(decoder: Decoder): Poll {
|
||||||
|
val asJson = JsonObjectSerializer.deserialize(decoder)
|
||||||
|
|
||||||
|
return when (asJson.getPrimitive(typeField).content) {
|
||||||
|
regularPollType -> Json.nonstrict.fromJson(
|
||||||
|
RegularPoll.serializer(),
|
||||||
|
asJson
|
||||||
|
)
|
||||||
|
quizPollType -> Json.nonstrict.fromJson(
|
||||||
|
QuizPoll.serializer(),
|
||||||
|
asJson
|
||||||
|
)
|
||||||
|
else -> UnknownPollType(
|
||||||
|
asJson.getPrimitive(idField).content,
|
||||||
|
asJson.getPrimitive(questionField).content,
|
||||||
|
Json.nonstrict.fromJson(
|
||||||
|
pollOptionsSerializer,
|
||||||
|
asJson.getArray(optionsField)
|
||||||
|
),
|
||||||
|
asJson.getPrimitive(totalVoterCountField).int,
|
||||||
|
asJson.getPrimitiveOrNull(isClosedField) ?.booleanOrNull ?: false,
|
||||||
|
asJson.getPrimitiveOrNull(isAnonymousField) ?.booleanOrNull ?: true,
|
||||||
|
asJson.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, obj: Poll) {
|
||||||
|
val asJson = when (obj) {
|
||||||
|
is RegularPoll -> Json.nonstrict.toJson(RegularPoll.serializer(), obj)
|
||||||
|
is QuizPoll -> Json.nonstrict.toJson(QuizPoll.serializer(), obj)
|
||||||
|
is UnknownPollType -> throw IllegalArgumentException("Currently unable to correctly serialize object of poll $obj")
|
||||||
|
}
|
||||||
|
val resultJson = JsonObject(
|
||||||
|
asJson.jsonObject + (typeField to when (obj) {
|
||||||
|
is RegularPoll -> JsonPrimitive(regularPollType)
|
||||||
|
is QuizPoll -> JsonPrimitive(quizPollType)
|
||||||
|
is UnknownPollType -> throw IllegalArgumentException("Currently unable to correctly serialize object of poll $obj")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
JsonObjectSerializer.serialize(encoder, resultJson)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types.polls
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.*
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PollAnswer(
|
||||||
|
@SerialName(pollIdField)
|
||||||
|
val pollId: PollIdentifier,
|
||||||
|
@SerialName(userField)
|
||||||
|
val user: User,
|
||||||
|
@SerialName(optionIdsField)
|
||||||
|
val chosen: List<Int>
|
||||||
|
)
|
@ -12,7 +12,7 @@ sealed class PollOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class AnonymousPollOption (
|
data class SimplePollOption (
|
||||||
@SerialName(textField)
|
@SerialName(textField)
|
||||||
override val text: String,
|
override val text: String,
|
||||||
@SerialName(votesCountField)
|
@SerialName(votesCountField)
|
||||||
@ -22,13 +22,13 @@ data class AnonymousPollOption (
|
|||||||
internal object PollOptionSerializer : KSerializer<PollOption> {
|
internal object PollOptionSerializer : KSerializer<PollOption> {
|
||||||
override val descriptor: SerialDescriptor = StringDescriptor.withName(PollOption::class.simpleName ?: "PollOption")
|
override val descriptor: SerialDescriptor = StringDescriptor.withName(PollOption::class.simpleName ?: "PollOption")
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): PollOption = AnonymousPollOption.serializer().deserialize(
|
override fun deserialize(decoder: Decoder): PollOption = SimplePollOption.serializer().deserialize(
|
||||||
decoder
|
decoder
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: PollOption) {
|
override fun serialize(encoder: Encoder, obj: PollOption) {
|
||||||
when (obj) {
|
when (obj) {
|
||||||
is AnonymousPollOption -> AnonymousPollOption.serializer().serialize(
|
is SimplePollOption -> SimplePollOption.serializer().serialize(
|
||||||
encoder,
|
encoder,
|
||||||
obj
|
obj
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types.update
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.PollAnswer
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
|
||||||
|
|
||||||
|
data class PollAnswerUpdate(
|
||||||
|
override val updateId: UpdateIdentifier,
|
||||||
|
override val data: PollAnswer
|
||||||
|
) : Update
|
@ -9,6 +9,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Telegr
|
|||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.PreCheckoutQuery
|
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.PreCheckoutQuery
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.ShippingQuery
|
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.ShippingQuery
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.Poll
|
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.Poll
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.PollAnswer
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdateType
|
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdateType
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
|
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.updateIdField
|
import com.github.insanusmokrassar.TelegramBotAPI.types.updateIdField
|
||||||
@ -33,7 +34,8 @@ internal data class RawUpdate constructor(
|
|||||||
private val callback_query: RawCallbackQuery? = null,
|
private val callback_query: RawCallbackQuery? = null,
|
||||||
private val shipping_query: ShippingQuery? = null,
|
private val shipping_query: ShippingQuery? = null,
|
||||||
private val pre_checkout_query: PreCheckoutQuery? = null,
|
private val pre_checkout_query: PreCheckoutQuery? = null,
|
||||||
private val poll: Poll? = null
|
private val poll: Poll? = null,
|
||||||
|
private val poll_answer: PollAnswer? = null
|
||||||
) {
|
) {
|
||||||
private var initedUpdate: Update? = null
|
private var initedUpdate: Update? = null
|
||||||
/**
|
/**
|
||||||
@ -55,6 +57,7 @@ internal data class RawUpdate constructor(
|
|||||||
shipping_query != null -> ShippingQueryUpdate(updateId, shipping_query)
|
shipping_query != null -> ShippingQueryUpdate(updateId, shipping_query)
|
||||||
pre_checkout_query != null -> PreCheckoutQueryUpdate(updateId, pre_checkout_query)
|
pre_checkout_query != null -> PreCheckoutQueryUpdate(updateId, pre_checkout_query)
|
||||||
poll != null -> PollUpdate(updateId, poll)
|
poll != null -> PollUpdate(updateId, poll)
|
||||||
|
poll_answer != null -> PollAnswerUpdate(updateId, poll_answer)
|
||||||
else -> UnknownUpdateType(
|
else -> UnknownUpdateType(
|
||||||
updateId,
|
updateId,
|
||||||
raw.toString()
|
raw.toString()
|
||||||
|
@ -22,6 +22,7 @@ data class UpdatesFilter(
|
|||||||
private val shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
private val shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
||||||
private val preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
private val preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
||||||
private val pollUpdateCallback: UpdateReceiver<PollUpdate>? = null,
|
private val pollUpdateCallback: UpdateReceiver<PollUpdate>? = null,
|
||||||
|
private val pollAnswerUpdateCallback: UpdateReceiver<PollAnswerUpdate>? = null,
|
||||||
private val unknownUpdateTypeCallback: UpdateReceiver<UnknownUpdateType>? = null
|
private val unknownUpdateTypeCallback: UpdateReceiver<UnknownUpdateType>? = null
|
||||||
) {
|
) {
|
||||||
val asUpdateReceiver: UpdateReceiver<Update> = this::invoke
|
val asUpdateReceiver: UpdateReceiver<Update> = this::invoke
|
||||||
@ -35,7 +36,8 @@ data class UpdatesFilter(
|
|||||||
callbackQueryCallback ?.let { UPDATE_CALLBACK_QUERY },
|
callbackQueryCallback ?.let { UPDATE_CALLBACK_QUERY },
|
||||||
shippingQueryCallback ?.let { UPDATE_SHIPPING_QUERY },
|
shippingQueryCallback ?.let { UPDATE_SHIPPING_QUERY },
|
||||||
preCheckoutQueryCallback ?.let { UPDATE_PRE_CHECKOUT_QUERY },
|
preCheckoutQueryCallback ?.let { UPDATE_PRE_CHECKOUT_QUERY },
|
||||||
pollUpdateCallback ?.let { UPDATE_POLL }
|
pollUpdateCallback ?.let { UPDATE_POLL },
|
||||||
|
pollAnswerUpdateCallback ?.let { UPDATE_POLL_ANSWER }
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun invoke(update: Update) {
|
suspend fun invoke(update: Update) {
|
||||||
@ -74,6 +76,7 @@ data class UpdatesFilter(
|
|||||||
is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(update)
|
is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(update)
|
||||||
is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update)
|
is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update)
|
||||||
is PollUpdate -> pollUpdateCallback ?.invoke(update)
|
is PollUpdate -> pollUpdateCallback ?.invoke(update)
|
||||||
|
is PollAnswerUpdate -> pollAnswerUpdateCallback ?.invoke(update)
|
||||||
is UnknownUpdateType -> unknownUpdateTypeCallback ?.invoke(update)
|
is UnknownUpdateType -> unknownUpdateTypeCallback ?.invoke(update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,6 +94,7 @@ fun createSimpleUpdateFilter(
|
|||||||
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
||||||
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
||||||
pollCallback: UpdateReceiver<PollUpdate>? = null,
|
pollCallback: UpdateReceiver<PollUpdate>? = null,
|
||||||
|
pollAnswerCallback: UpdateReceiver<PollAnswerUpdate>? = null,
|
||||||
unknownCallback: UpdateReceiver<UnknownUpdateType>? = null
|
unknownCallback: UpdateReceiver<UnknownUpdateType>? = null
|
||||||
): UpdatesFilter = UpdatesFilter(
|
): UpdatesFilter = UpdatesFilter(
|
||||||
messageCallback = messageCallback,
|
messageCallback = messageCallback,
|
||||||
@ -107,5 +111,6 @@ fun createSimpleUpdateFilter(
|
|||||||
shippingQueryCallback = shippingQueryCallback,
|
shippingQueryCallback = shippingQueryCallback,
|
||||||
preCheckoutQueryCallback = preCheckoutQueryCallback,
|
preCheckoutQueryCallback = preCheckoutQueryCallback,
|
||||||
pollUpdateCallback = pollCallback,
|
pollUpdateCallback = pollCallback,
|
||||||
|
pollAnswerUpdateCallback = pollAnswerCallback,
|
||||||
unknownUpdateTypeCallback = unknownCallback
|
unknownUpdateTypeCallback = unknownCallback
|
||||||
)
|
)
|
||||||
|
@ -43,6 +43,7 @@ fun RequestsExecutor.startGettingOfUpdates(
|
|||||||
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
||||||
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
||||||
pollCallback: UpdateReceiver<PollUpdate>? = null,
|
pollCallback: UpdateReceiver<PollUpdate>? = null,
|
||||||
|
pollAnswerCallback: UpdateReceiver<PollAnswerUpdate>? = null,
|
||||||
timeoutMillis: Long = 30 * 1000,
|
timeoutMillis: Long = 30 * 1000,
|
||||||
scope: CoroutineScope = GlobalScope
|
scope: CoroutineScope = GlobalScope
|
||||||
): UpdatesPoller {
|
): UpdatesPoller {
|
||||||
@ -60,7 +61,8 @@ fun RequestsExecutor.startGettingOfUpdates(
|
|||||||
callbackQueryCallback,
|
callbackQueryCallback,
|
||||||
shippingQueryCallback,
|
shippingQueryCallback,
|
||||||
preCheckoutQueryCallback,
|
preCheckoutQueryCallback,
|
||||||
pollCallback
|
pollCallback,
|
||||||
|
pollAnswerCallback
|
||||||
)
|
)
|
||||||
return startGettingOfUpdates(
|
return startGettingOfUpdates(
|
||||||
timeoutMillis,
|
timeoutMillis,
|
||||||
@ -82,6 +84,7 @@ fun RequestsExecutor.startGettingOfUpdates(
|
|||||||
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
|
||||||
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
|
||||||
pollCallback: UpdateReceiver<PollUpdate>? = null,
|
pollCallback: UpdateReceiver<PollUpdate>? = null,
|
||||||
|
pollAnswerCallback: UpdateReceiver<PollAnswerUpdate>? = null,
|
||||||
timeoutMillis: Long = 30 * 1000,
|
timeoutMillis: Long = 30 * 1000,
|
||||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
): UpdatesPoller = startGettingOfUpdates(
|
): UpdatesPoller = startGettingOfUpdates(
|
||||||
@ -99,6 +102,7 @@ fun RequestsExecutor.startGettingOfUpdates(
|
|||||||
shippingQueryCallback = shippingQueryCallback,
|
shippingQueryCallback = shippingQueryCallback,
|
||||||
preCheckoutQueryCallback = preCheckoutQueryCallback,
|
preCheckoutQueryCallback = preCheckoutQueryCallback,
|
||||||
pollCallback = pollCallback,
|
pollCallback = pollCallback,
|
||||||
|
pollAnswerCallback = pollAnswerCallback,
|
||||||
timeoutMillis = timeoutMillis,
|
timeoutMillis = timeoutMillis,
|
||||||
scope = scope
|
scope = scope
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.types
|
|||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun User.javaLocale(): Locale? = languageCode ?.let {
|
fun CommonUser.javaLocale(): Locale? = languageCode ?.let {
|
||||||
Locale.forLanguageTag(it)
|
Locale.forLanguageTag(it)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user