1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2026-03-03 17:32:23 +00:00

add support of style and iconEmojiCustomId

This commit is contained in:
2026-02-16 22:57:45 +06:00
parent 85fb7e42e5
commit c4f2566b71
4 changed files with 194 additions and 26 deletions

View File

@@ -329,6 +329,8 @@ const val checklistMessageField = "checklist_message"
const val markedAsDoneTaskIdsField = "marked_as_done_task_ids" const val markedAsDoneTaskIdsField = "marked_as_done_task_ids"
const val markedAsNotDoneTaskIdsField = "marked_as_not_done_task_ids" const val markedAsNotDoneTaskIdsField = "marked_as_not_done_task_ids"
const val styleField = "style"
const val requestContactField = "request_contact" const val requestContactField = "request_contact"
const val requestLocationField = "request_location" const val requestLocationField = "request_location"
const val requestPollField = "request_poll" const val requestPollField = "request_poll"

View File

@@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardButtonStyle
import dev.inmo.tgbotapi.types.games.CallbackGame import dev.inmo.tgbotapi.types.games.CallbackGame
import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import kotlinx.serialization.* import kotlinx.serialization.*
@@ -18,6 +19,9 @@ import kotlinx.serialization.json.*
@ClassCastsIncluded @ClassCastsIncluded
sealed interface InlineKeyboardButton { sealed interface InlineKeyboardButton {
val text: String val text: String
val style: KeyboardButtonStyle?
val iconCustomEmojiId: CustomEmojiId?
} }
@Serializable @Serializable
@@ -28,6 +32,10 @@ data class UnknownInlineKeyboardButton (
get() = runCatching { get() = runCatching {
rawData.jsonObject[textField] ?.jsonPrimitive ?.content rawData.jsonObject[textField] ?.jsonPrimitive ?.content
}.getOrNull() ?: "" }.getOrNull() ?: ""
override val style: KeyboardButtonStyle?
get() = null
override val iconCustomEmojiId: CustomEmojiId?
get() = null
} }
/** /**
@@ -36,7 +44,11 @@ data class UnknownInlineKeyboardButton (
*/ */
@Serializable @Serializable
data class PayInlineKeyboardButton( data class PayInlineKeyboardButton(
override val text: String override val text: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton { ) : InlineKeyboardButton {
@ExperimentalSerializationApi @ExperimentalSerializationApi
@EncodeDefault @EncodeDefault
@@ -58,7 +70,11 @@ data class CallbackDataInlineKeyboardButton(
* You will receive this data in [dev.inmo.tgbotapi.types.queries.callback.DataCallbackQuery.data] field * You will receive this data in [dev.inmo.tgbotapi.types.queries.callback.DataCallbackQuery.data] field
*/ */
@SerialName(callbackDataField) @SerialName(callbackDataField)
val callbackData: String val callbackData: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -67,7 +83,11 @@ data class CallbackDataInlineKeyboardButton(
@Serializable @Serializable
data class CallbackGameInlineKeyboardButton( data class CallbackGameInlineKeyboardButton(
@SerialName(textField) @SerialName(textField)
override val text: String override val text: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton { ) : InlineKeyboardButton {
@SerialName(callbackGameField) @SerialName(callbackGameField)
@EncodeDefault @EncodeDefault
@@ -81,7 +101,11 @@ data class CallbackGameInlineKeyboardButton(
data class LoginURLInlineKeyboardButton( data class LoginURLInlineKeyboardButton(
override val text: String, override val text: String,
@SerialName(loginUrlField) @SerialName(loginUrlField)
val loginUrl: LoginURL val loginUrl: LoginURL,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -98,7 +122,11 @@ data class LoginURLInlineKeyboardButton(
data class SwitchInlineQueryCurrentChatInlineKeyboardButton( data class SwitchInlineQueryCurrentChatInlineKeyboardButton(
override val text: String, override val text: String,
@SerialName(switchInlineQueryCurrentChatField) @SerialName(switchInlineQueryCurrentChatField)
val switchInlineQueryCurrentChat: String val switchInlineQueryCurrentChat: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -115,7 +143,11 @@ data class SwitchInlineQueryCurrentChatInlineKeyboardButton(
data class SwitchInlineQueryChosenChatInlineKeyboardButton( data class SwitchInlineQueryChosenChatInlineKeyboardButton(
override val text: String, override val text: String,
@SerialName(switchInlineQueryChosenChatField) @SerialName(switchInlineQueryChosenChatField)
val parameters: SwitchInlineQueryChosenChat val parameters: SwitchInlineQueryChosenChat,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -131,7 +163,11 @@ data class SwitchInlineQueryChosenChatInlineKeyboardButton(
data class SwitchInlineQueryInlineKeyboardButton( data class SwitchInlineQueryInlineKeyboardButton(
override val text: String, override val text: String,
@SerialName(switchInlineQueryField) @SerialName(switchInlineQueryField)
val switchInlineQuery: String val switchInlineQuery: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -141,7 +177,11 @@ data class SwitchInlineQueryInlineKeyboardButton(
data class URLInlineKeyboardButton( data class URLInlineKeyboardButton(
override val text: String, override val text: String,
@SerialName(urlField) @SerialName(urlField)
val url: String val url: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -151,7 +191,11 @@ data class URLInlineKeyboardButton(
data class CopyTextButton( data class CopyTextButton(
override val text: String, override val text: String,
@SerialName(copyTextField) @SerialName(copyTextField)
val data: CopyTextButtonData val data: CopyTextButtonData,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton
/** /**
@@ -162,5 +206,9 @@ data class CopyTextButton(
data class WebAppInlineKeyboardButton( data class WebAppInlineKeyboardButton(
override val text: String, override val text: String,
@SerialName(webAppField) @SerialName(webAppField)
val webApp: WebAppInfo val webApp: WebAppInfo,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : InlineKeyboardButton ) : InlineKeyboardButton

View File

@@ -19,6 +19,9 @@ import kotlinx.serialization.json.*
@Serializable(KeyboardButtonSerializer::class) @Serializable(KeyboardButtonSerializer::class)
sealed interface KeyboardButton { sealed interface KeyboardButton {
val text: String val text: String
val style: KeyboardButtonStyle?
val iconCustomEmojiId: CustomEmojiId?
} }
/** /**
@@ -30,7 +33,11 @@ sealed interface KeyboardButton {
*/ */
@Serializable @Serializable
data class SimpleKeyboardButton( data class SimpleKeyboardButton(
override val text: String override val text: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton ) : KeyboardButton
@ConsistentCopyVisibility @ConsistentCopyVisibility
@@ -38,7 +45,12 @@ data class SimpleKeyboardButton(
data class UnknownKeyboardButton internal constructor( data class UnknownKeyboardButton internal constructor(
override val text: String, override val text: String,
val raw: String val raw: String
) : KeyboardButton ) : KeyboardButton {
override val style: KeyboardButtonStyle?
get() = null
override val iconCustomEmojiId: CustomEmojiId?
get() = null
}
/** /**
* Private chats only. When user will tap on this button, his contact (with his number and name) will be sent to the bot. You will be able * Private chats only. When user will tap on this button, his contact (with his number and name) will be sent to the bot. You will be able
@@ -49,7 +61,11 @@ data class UnknownKeyboardButton internal constructor(
*/ */
@Serializable @Serializable
data class RequestContactKeyboardButton( data class RequestContactKeyboardButton(
override val text: String override val text: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton { ) : KeyboardButton {
@SerialName(requestContactField) @SerialName(requestContactField)
@EncodeDefault @EncodeDefault
@@ -65,7 +81,11 @@ data class RequestContactKeyboardButton(
*/ */
@Serializable @Serializable
data class RequestLocationKeyboardButton( data class RequestLocationKeyboardButton(
override val text: String override val text: String,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton { ) : KeyboardButton {
@SerialName(requestLocationField) @SerialName(requestLocationField)
@Required @Required
@@ -82,7 +102,11 @@ data class RequestLocationKeyboardButton(
data class WebAppKeyboardButton( data class WebAppKeyboardButton(
override val text: String, override val text: String,
@SerialName(webAppField) @SerialName(webAppField)
val webApp: WebAppInfo val webApp: WebAppInfo,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton ) : KeyboardButton
/** /**
@@ -96,7 +120,11 @@ data class WebAppKeyboardButton(
data class RequestPollKeyboardButton( data class RequestPollKeyboardButton(
override val text: String, override val text: String,
@SerialName(requestPollField) @SerialName(requestPollField)
val requestPoll: KeyboardButtonPollType val requestPoll: KeyboardButtonPollType,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton ) : KeyboardButton
/** /**
@@ -114,7 +142,11 @@ data class RequestPollKeyboardButton(
data class RequestUserKeyboardButton( data class RequestUserKeyboardButton(
override val text: String, override val text: String,
@SerialName(requestUsersField) @SerialName(requestUsersField)
val requestUsers: KeyboardButtonRequestUsers val requestUsers: KeyboardButtonRequestUsers,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton ) : KeyboardButton
/** /**
@@ -132,7 +164,11 @@ data class RequestUserKeyboardButton(
data class RequestChatKeyboardButton( data class RequestChatKeyboardButton(
override val text: String, override val text: String,
@SerialName(requestChatField) @SerialName(requestChatField)
val requestChat: KeyboardButtonRequestChat val requestChat: KeyboardButtonRequestChat,
@SerialName(iconCustomEmojiIdField)
override val iconCustomEmojiId: CustomEmojiId? = null,
@SerialName(styleField)
override val style: KeyboardButtonStyle? = null
) : KeyboardButton ) : KeyboardButton
@RiskFeature @RiskFeature
@@ -142,42 +178,73 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
override fun deserialize(decoder: Decoder): KeyboardButton { override fun deserialize(decoder: Decoder): KeyboardButton {
val asJson = internalSerializer.deserialize(decoder) val asJson = internalSerializer.deserialize(decoder)
val styleData: KeyboardButtonStyle? by lazy {
(asJson as? JsonObject)
?.get(styleField)
?.jsonPrimitive
?.let { nonstrictJsonFormat.decodeFromJsonElement(KeyboardButtonStyle.serializer(), it) }
}
val iconCustomEmojiIdData: CustomEmojiId? by lazy {
(asJson as? JsonObject)
?.get(iconCustomEmojiIdField)
?.jsonPrimitive
?.let { nonstrictJsonFormat.decodeFromJsonElement(CustomEmojiId.serializer(), it) }
}
return when { return when {
asJson is JsonPrimitive -> SimpleKeyboardButton(asJson.content) asJson is JsonPrimitive -> SimpleKeyboardButton(
asJson.content
)
asJson is JsonObject && asJson[requestContactField] != null -> RequestContactKeyboardButton( asJson is JsonObject && asJson[requestContactField] != null -> RequestContactKeyboardButton(
asJson[textField]!!.jsonPrimitive.content asJson[textField]!!.jsonPrimitive.content,
iconCustomEmojiIdData,
styleData
) )
asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton( asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton(
asJson[textField]!!.jsonPrimitive.content asJson[textField]!!.jsonPrimitive.content,
iconCustomEmojiIdData,
styleData
) )
asJson is JsonObject && asJson[webAppField] != null -> WebAppKeyboardButton( asJson is JsonObject && asJson[webAppField] != null -> WebAppKeyboardButton(
asJson[textField]!!.jsonPrimitive.content, asJson[textField]!!.jsonPrimitive.content,
nonstrictJsonFormat.decodeFromJsonElement( nonstrictJsonFormat.decodeFromJsonElement(
WebAppInfo.serializer(), WebAppInfo.serializer(),
asJson[webAppField]!! asJson[webAppField]!!
) ),
iconCustomEmojiIdData,
styleData
) )
asJson is JsonObject && asJson[requestPollField] != null -> RequestPollKeyboardButton( asJson is JsonObject && asJson[requestPollField] != null -> RequestPollKeyboardButton(
asJson[textField]!!.jsonPrimitive.content, asJson[textField]!!.jsonPrimitive.content,
nonstrictJsonFormat.decodeFromJsonElement( nonstrictJsonFormat.decodeFromJsonElement(
KeyboardButtonPollTypeSerializer, KeyboardButtonPollTypeSerializer,
asJson[requestPollField] ?.jsonObject ?: buildJsonObject { } asJson[requestPollField] ?.jsonObject ?: buildJsonObject { }
) ),
iconCustomEmojiIdData,
styleData
) )
asJson is JsonObject && asJson[requestUsersField] != null -> RequestUserKeyboardButton( asJson is JsonObject && asJson[requestUsersField] != null -> RequestUserKeyboardButton(
asJson[textField]!!.jsonPrimitive.content, asJson[textField]!!.jsonPrimitive.content,
nonstrictJsonFormat.decodeFromJsonElement( nonstrictJsonFormat.decodeFromJsonElement(
KeyboardButtonRequestUsers.serializer(), KeyboardButtonRequestUsers.serializer(),
asJson[requestUsersField] ?.jsonObject ?: buildJsonObject { } asJson[requestUsersField] ?.jsonObject ?: buildJsonObject { }
) ),
iconCustomEmojiIdData,
styleData
) )
asJson is JsonObject && asJson[requestChatField] != null -> RequestChatKeyboardButton( asJson is JsonObject && asJson[requestChatField] != null -> RequestChatKeyboardButton(
asJson[textField]!!.jsonPrimitive.content, asJson[textField]!!.jsonPrimitive.content,
nonstrictJsonFormat.decodeFromJsonElement( nonstrictJsonFormat.decodeFromJsonElement(
KeyboardButtonRequestChat.serializer(), KeyboardButtonRequestChat.serializer(),
asJson[requestChatField] ?.jsonObject ?: buildJsonObject { } asJson[requestChatField] ?.jsonObject ?: buildJsonObject { }
) ),
iconCustomEmojiIdData,
styleData
)
asJson is JsonObject && asJson[textField] != null -> SimpleKeyboardButton(
asJson[textField]!!.jsonPrimitive.content,
iconCustomEmojiIdData,
styleData
) )
else -> UnknownKeyboardButton( else -> UnknownKeyboardButton(
when (asJson) { when (asJson) {
@@ -196,7 +263,7 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.serializer().serialize(encoder, value) is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.serializer().serialize(encoder, value)
is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value) is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value)
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value) is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
is SimpleKeyboardButton -> encoder.encodeString(value.text) is SimpleKeyboardButton -> SimpleKeyboardButton.serializer().serialize(encoder, value)
is RequestUserKeyboardButton -> RequestUserKeyboardButton.serializer().serialize(encoder, value) is RequestUserKeyboardButton -> RequestUserKeyboardButton.serializer().serialize(encoder, value)
is RequestChatKeyboardButton -> RequestChatKeyboardButton.serializer().serialize(encoder, value) is RequestChatKeyboardButton -> RequestChatKeyboardButton.serializer().serialize(encoder, value)
is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw)) is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw))

View File

@@ -0,0 +1,51 @@
package dev.inmo.tgbotapi.types.buttons
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializable(KeyboardButtonStyle.Serializer::class)
sealed interface KeyboardButtonStyle {
val name: String
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(KeyboardButtonStyle.Serializer::class)
data object Danger : KeyboardButtonStyle { override val name: String = "danger" }
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(KeyboardButtonStyle.Serializer::class)
data object Success : KeyboardButtonStyle { override val name: String = "success" }
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(KeyboardButtonStyle.Serializer::class)
data object Primary : KeyboardButtonStyle { override val name: String = "primary" }
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(KeyboardButtonStyle.Serializer::class)
data class Custom(override val name: String = "primary") : KeyboardButtonStyle
object Serializer : KSerializer<KeyboardButtonStyle> {
override val descriptor: SerialDescriptor
get() = String.serializer().descriptor
override fun serialize(
encoder: Encoder,
value: KeyboardButtonStyle
) {
encoder.encodeString(value.name)
}
override fun deserialize(decoder: Decoder): KeyboardButtonStyle {
return when (val rawValue = decoder.decodeString()) {
Danger.name -> Danger
Success.name -> Success
Primary.name -> Primary
else -> Custom(rawValue)
}
}
}
}