diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt index 85f65a2b13..a3f95bce73 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt @@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.games.CallbackGame +import dev.inmo.tgbotapi.types.webapps.WebAppInfo import kotlinx.serialization.* import kotlinx.serialization.json.* @@ -120,3 +121,14 @@ data class URLInlineKeyboardButton( @SerialName(urlField) val url: String ) : InlineKeyboardButton + +/** + * Button with [WebAppInfo]. Web App will be launched when the button is pressed. The Web App will be able to send a + * `web_app_data` service message. **Available in private chats only**. + */ +@Serializable +data class WebAppInlineKeyboardButton( + override val text: String, + @SerialName(webAppField) + val webApp: WebAppInfo +) : InlineKeyboardButton diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt index 1beef89dd8..70005d12c7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButtonSerializer.kt @@ -48,6 +48,7 @@ object InlineKeyboardButtonSerializer : KSerializer { is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value) is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value) is URLInlineKeyboardButton -> URLInlineKeyboardButton.serializer().serialize(encoder, value) + is WebAppInlineKeyboardButton -> WebAppInlineKeyboardButton.serializer().serialize(encoder, value) is CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value) is UnknownInlineKeyboardButton -> JsonElement.serializer().serialize(encoder, value.rawData) } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/KeyboardButton.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/KeyboardButton.kt index 688dd3da03..4226bc94d2 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/KeyboardButton.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/KeyboardButton.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.types.buttons import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import kotlinx.serialization.* @@ -63,10 +64,22 @@ data class RequestLocationKeyboardButton( override val text: String ) : KeyboardButton { @SerialName(requestLocationField) - @EncodeDefault + @Required val requestLocation: Boolean = true } +/** + * Private chats only. Description of the Web App that will be launched when the user presses the button. The Web App + * will be able to send an arbitrary message on behalf of the user using the method `answerWebAppQuery`. Available only + * in private chats between a user and the bot. + */ +@Serializable +data class WebAppKeyboardButton( + override val text: String, + @SerialName(webAppField) + val webApp: WebAppInfo +) : KeyboardButton + /** * Private chats only. When user will tap on this button, he will be asked for the poll with [requestPoll] options. You will be able * to catch this poll in updates and data using [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPoll] in @@ -97,6 +110,13 @@ object KeyboardButtonSerializer : KSerializer { asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton( asJson[textField]!!.jsonPrimitive.content ) + asJson is JsonObject && asJson[webAppField] != null -> WebAppKeyboardButton( + asJson[textField]!!.jsonPrimitive.content, + nonstrictJsonFormat.decodeFromJsonElement( + WebAppInfo.serializer(), + asJson[webAppField]!! + ) + ) asJson is JsonObject && asJson[requestPollField] != null -> RequestPollKeyboardButton( asJson[textField]!!.jsonPrimitive.content, nonstrictJsonFormat.decodeFromJsonElement( @@ -119,6 +139,7 @@ object KeyboardButtonSerializer : KSerializer { when (value) { is RequestContactKeyboardButton -> RequestContactKeyboardButton.serializer().serialize(encoder, value) is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.serializer().serialize(encoder, value) + is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value) is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value) is SimpleKeyboardButton -> encoder.encodeString(value.text) is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw)) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt index 071effbcbb..ed84b41075 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt @@ -2514,6 +2514,16 @@ inline fun InlineKeyboardButton.asURLInlineKeyboardButton(): URLInlineKeyboardBu inline fun InlineKeyboardButton.requireURLInlineKeyboardButton(): URLInlineKeyboardButton = this as URLInlineKeyboardButton +@PreviewFeature +inline fun InlineKeyboardButton.whenWebAppKeyboardButton(block: (WebAppKeyboardButton) -> T) = asWebAppKeyboardButton() ?.let(block) + +@PreviewFeature +inline fun InlineKeyboardButton.asWebAppKeyboardButton(): WebAppKeyboardButton? = this as? WebAppKeyboardButton + +@PreviewFeature +inline fun InlineKeyboardButton.requireWebAppKeyboardButton(): WebAppKeyboardButton = + this as WebAppKeyboardButton + @PreviewFeature inline fun InlineKeyboardButton.whenUnknownInlineKeyboardButton(block: (UnknownInlineKeyboardButton) -> T) = asUnknownInlineKeyboardButton() ?.let(block) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt index 1d348269b8..d34fc9a936 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt @@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.extensions.utils.types.buttons import dev.inmo.tgbotapi.types.LoginURL import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.* import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup +import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.utils.MatrixBuilder import dev.inmo.tgbotapi.utils.RowBuilder @@ -128,3 +129,14 @@ inline fun InlineKeyboardRowBuilder.urlButton( text: String, url: String ) = add(URLInlineKeyboardButton(text, url)) + +/** + * Creates and put [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only + * + * @see inlineKeyboard + * @see InlineKeyboardBuilder.row + */ +inline fun InlineKeyboardRowBuilder.webAppButton( + text: String, + webApp: WebAppInfo +) = add(WebAppInlineKeyboardButton(text, webApp)) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/ReplyKeyboardBuilder.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/ReplyKeyboardBuilder.kt index ea36d5cfc4..78e86fb8d8 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/ReplyKeyboardBuilder.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/ReplyKeyboardBuilder.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.extensions.utils.types.buttons import dev.inmo.tgbotapi.types.buttons.* +import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.utils.MatrixBuilder import dev.inmo.tgbotapi.utils.RowBuilder @@ -98,3 +99,14 @@ inline fun ReplyKeyboardRowBuilder.requestPollButton( text: String, pollType: KeyboardButtonPollType ) = add(RequestPollKeyboardButton(text, pollType)) + +/** + * Creates and put [WebAppKeyboardButton] + * + * @see replyKeyboard + * @see ReplyKeyboardBuilder.row + */ +inline fun ReplyKeyboardRowBuilder.webAppButton( + text: String, + webApp: WebAppInfo +) = add(WebAppKeyboardButton(text, webApp))