1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-29 13:38:43 +00:00

Compare commits

..

No commits in common. "930507ab80eb7fe0e475a8f4aa08048bf1b6d245" and "4c7bfe99c013fe5fb5c1521f0efa795fe20aa3cf" have entirely different histories.

69 changed files with 154 additions and 1301 deletions

View File

@ -1,14 +1,5 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 0.38.14
__This update contains including of [Telegram Bot API 6.0](https://core.telegram.org/bots/api-changelog#april-16-2022)__
* `Core`:
* Constructor of `UnknownInlineKeyboardButton` is not internal and can be created with any `json`
* `WebApps`:
* Created 🎉
## 0.38.13 ## 0.38.13
* `Core`: * `Core`:

View File

@ -1,4 +1,4 @@
# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.0-blue)](https://core.telegram.org/bots/api-changelog#april-16-2022) # TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-5.7-blue)](https://core.telegram.org/bots/api-changelog#january-31-2022)
| [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://github.com/InsanusMokrassar/TelegramBotAPI/workflows/Build/badge.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue&logo=google-sheets)](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) [![Chat in Telegram](https://img.shields.io/static/v1?label=Telegram&message=Chat&color=blue&logo=telegram)](https://t.me/InMoTelegramBotAPI) | | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://github.com/InsanusMokrassar/TelegramBotAPI/workflows/Build/badge.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue&logo=google-sheets)](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) [![Chat in Telegram](https://img.shields.io/static/v1?label=Telegram&message=Chat&color=blue&logo=telegram)](https://t.me/InMoTelegramBotAPI) |
|:---:| |:---:|

View File

@ -40,17 +40,11 @@ kotlin {
dependencies { dependencies {
implementation kotlin('stdlib') implementation kotlin('stdlib')
api project(":tgbotapi.core") rootProject.subprojects.forEach {
api project(":tgbotapi.api") if (it != project) {
api project(":tgbotapi.utils") api it
api project(":tgbotapi.behaviour_builder") }
api project(":tgbotapi.behaviour_builder.fsm") }
api project(":tgbotapi")
}
}
jsMain {
dependencies {
api project(":tgbotapi.webapps")
} }
} }
} }

View File

@ -20,6 +20,6 @@ javax_activation_version=1.1.1
dokka_version=1.6.10 dokka_version=1.6.10
library_group=dev.inmo library_group=dev.inmo
library_version=0.38.14 library_version=0.38.13
github_release_plugin_version=2.3.7 github_release_plugin_version=2.3.7

View File

@ -21,5 +21,4 @@ include ":tgbotapi.extensions.utils"
include ":tgbotapi.extensions.behaviour_builder" include ":tgbotapi.extensions.behaviour_builder"
include ":tgbotapi.extensions.behaviour_builder.fsm" include ":tgbotapi.extensions.behaviour_builder.fsm"
include ":tgbotapi" include ":tgbotapi"
include ":tgbotapi.webapps"
include ":docs" include ":docs"

View File

@ -13,7 +13,7 @@ import io.ktor.client.engine.*
*/ */
fun telegramBot( fun telegramBot(
urlsKeeper: TelegramAPIUrlsKeeper, urlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient = HttpClient() client: HttpClient
): TelegramBot = telegramBot(urlsKeeper) { ): TelegramBot = telegramBot(urlsKeeper) {
this.client = client this.client = client
} }
@ -66,7 +66,7 @@ inline fun telegramBot(
inline fun telegramBot( inline fun telegramBot(
token: String, token: String,
apiUrl: String = telegramBotAPIDefaultUrl, apiUrl: String = telegramBotAPIDefaultUrl,
client: HttpClient = HttpClient() client: HttpClient
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client) ): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client)
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")

View File

@ -1,16 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.answers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.answers.AnswerWebAppQuery
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
import dev.inmo.tgbotapi.types.WebAppQueryId
suspend fun TelegramBot.answerWebAppQuery(
webAppQueryId: WebAppQueryId,
result: InlineQueryResult
) = execute(AnswerWebAppQuery(webAppQueryId, result))
suspend fun TelegramBot.answer(
webAppQueryId: WebAppQueryId,
result: InlineQueryResult
) = execute(AnswerWebAppQuery(webAppQueryId, result))

View File

@ -1,13 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.bot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.bot.ClearMyDefaultAdministratorRights
import dev.inmo.tgbotapi.types.ChatAdministratorRightsImpl
suspend fun TelegramBot.clearMyDefaultAdministratorRights(
forChannels: Boolean? = null
) = execute(ClearMyDefaultAdministratorRights(forChannels))
suspend fun TelegramBot.clearMyDefaultAdministratorRightsForChannels() = clearMyDefaultAdministratorRights(forChannels = true)
suspend fun TelegramBot.clearMyDefaultAdministratorRightsForGroupsAndSupergroups() = clearMyDefaultAdministratorRights(forChannels = false)

View File

@ -1,12 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.bot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.bot.GetMyDefaultAdministratorRights
suspend fun TelegramBot.getMyDefaultAdministratorRights(
forChannels: Boolean? = null
) = execute(GetMyDefaultAdministratorRights(forChannels))
suspend fun TelegramBot.getMyDefaultAdministratorRightsForChannels() = getMyDefaultAdministratorRights(forChannels = true)
suspend fun TelegramBot.getMyDefaultAdministratorRightsForGroupsAndSupergroups() = getMyDefaultAdministratorRights(forChannels = false)

View File

@ -1,18 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.bot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.bot.SetMyDefaultAdministratorRights
import dev.inmo.tgbotapi.types.ChatAdministratorRightsImpl
suspend fun TelegramBot.setMyDefaultAdministratorRights(
rights: ChatAdministratorRightsImpl,
forChannels: Boolean? = null
) = execute(SetMyDefaultAdministratorRights(rights, forChannels))
suspend fun TelegramBot.setMyDefaultAdministratorRightsForChannels(
rights: ChatAdministratorRightsImpl
) = setMyDefaultAdministratorRights(rights, forChannels = true)
suspend fun TelegramBot.setMyDefaultAdministratorRightsForGroupsAndSupergroups(
rights: ChatAdministratorRightsImpl
) = setMyDefaultAdministratorRights(rights, forChannels = false)

View File

@ -1,15 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.chat.get
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.get.GetChatMenuButton
import dev.inmo.tgbotapi.requests.chat.modify.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.PrivateChat
suspend fun TelegramBot.getChatMenuButton(
chatId: ChatId
) = execute(GetChatMenuButton(chatId))
suspend fun TelegramBot.getChatMenuButton(
chat: PrivateChat
) = getChatMenuButton(chat.id)

View File

@ -1,8 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.chat.get
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.get.GetDefaultChatMenuButton
import dev.inmo.tgbotapi.requests.chat.modify.SetDefaultChatMenuButton
import dev.inmo.tgbotapi.types.MenuButton
suspend fun TelegramBot.getDefaultChatMenuButton() = execute(GetDefaultChatMenuButton)

View File

@ -18,7 +18,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers: Boolean? = null, canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null, canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? canManageChat: Boolean?
) = execute( ) = execute(
PromoteChatMember( PromoteChatMember(
@ -34,7 +34,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers, canRestrictMembers,
canPinMessages, canPinMessages,
canPromoteMembers, canPromoteMembers,
canManageVideoChats, canManageVoiceChats,
canManageChat canManageChat
) )
) )
@ -52,7 +52,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers: Boolean? = null, canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null, canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? = null canManageChat: Boolean? = null
) = promoteChatMember( ) = promoteChatMember(
chat.id, chat.id,
@ -67,7 +67,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers, canRestrictMembers,
canPinMessages, canPinMessages,
canPromoteMembers, canPromoteMembers,
canManageVideoChats, canManageVoiceChats,
canManageChat canManageChat
) )
@ -84,7 +84,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers: Boolean? = null, canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null, canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? = null canManageChat: Boolean? = null
) = promoteChatMember( ) = promoteChatMember(
chatId, chatId,
@ -99,7 +99,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers, canRestrictMembers,
canPinMessages, canPinMessages,
canPromoteMembers, canPromoteMembers,
canManageVideoChats, canManageVoiceChats,
canManageChat canManageChat
) )
@ -116,7 +116,7 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers: Boolean? = null, canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null, canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? = null canManageChat: Boolean? = null
) = promoteChatMember( ) = promoteChatMember(
chat.id, chat.id,
@ -131,6 +131,6 @@ suspend fun TelegramBot.promoteChatMember(
canRestrictMembers, canRestrictMembers,
canPinMessages, canPinMessages,
canPromoteMembers, canPromoteMembers,
canManageVideoChats, canManageVoiceChats,
canManageChat canManageChat
) )

View File

@ -1,16 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.chat.modify
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.modify.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.PrivateChat
suspend fun TelegramBot.setChatMenuButton(
chatId: ChatId,
menuButton: MenuButton
) = execute(SetChatMenuButton(chatId, menuButton))
suspend fun TelegramBot.setChatMenuButton(
chat: PrivateChat,
menuButton: MenuButton
) = setChatMenuButton(chat.id, menuButton)

View File

@ -1,9 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.chat.modify
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.modify.SetDefaultChatMenuButton
import dev.inmo.tgbotapi.types.MenuButton
suspend fun TelegramBot.setDefaultChatMenuButton(
menuButton: MenuButton
) = execute(SetDefaultChatMenuButton(menuButton))

View File

@ -10,7 +10,6 @@ import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
import dev.inmo.tgbotapi.types.message.PrivateEventMessage
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
@ -90,66 +89,33 @@ suspend fun BehaviourContext.waitChatEvents(
mapper: EventMessageToEventMapper<ChatEvent>? = null mapper: EventMessageToEventMapper<ChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper) ) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatEvents( suspend fun BehaviourContext.waitVoiceChatEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null, filter: SimpleFilter<ChatEventMessage<VoiceChatEvent>>? = null,
mapper: EventMessageToEventMapper<VideoChatEvent>? = null mapper: EventMessageToEventMapper<VoiceChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper) ) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatStartedEvents( suspend fun BehaviourContext.waitVoiceChatStartedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null, filter: SimpleFilter<ChatEventMessage<VoiceChatStarted>>? = null,
mapper: EventMessageToEventMapper<VideoChatStarted>? = null mapper: EventMessageToEventMapper<VoiceChatStarted>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper) ) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatEndedEvents( suspend fun BehaviourContext.waitVoiceChatEndedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null, filter: SimpleFilter<ChatEventMessage<VoiceChatEnded>>? = null,
mapper: EventMessageToEventMapper<VideoChatEnded>? = null mapper: EventMessageToEventMapper<VoiceChatEnded>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper) ) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents( suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null, filter: SimpleFilter<ChatEventMessage<VoiceChatParticipantsInvited>>? = null,
mapper: EventMessageToEventMapper<VideoChatParticipantsInvited>? = null mapper: EventMessageToEventMapper<VoiceChatParticipantsInvited>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
mapper: EventMessageToEventMapper<VideoChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatStartedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
mapper: EventMessageToEventMapper<VideoChatStarted>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatEndedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
mapper: EventMessageToEventMapper<VideoChatEnded>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatParticipantsInvitedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
mapper: EventMessageToEventMapper<VideoChatParticipantsInvited>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper) ) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents( suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents(
@ -275,10 +241,3 @@ suspend fun BehaviourContext.waitUserLoggedInEvents(
filter: SimpleFilter<ChatEventMessage<UserLoggedIn>>? = null, filter: SimpleFilter<ChatEventMessage<UserLoggedIn>>? = null,
mapper: EventMessageToEventMapper<UserLoggedIn>? = null mapper: EventMessageToEventMapper<UserLoggedIn>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper) ) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitWebAppDataEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<PrivateEventMessage<WebAppData>>? = null,
mapper: EventMessageToEventMapper<WebAppData>? = null
) = waitEvents(count, initRequest, errorFactory, filter ?.let { { it is PrivateEventMessage && filter(it) } }, mapper)

View File

@ -12,7 +12,6 @@ import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage
import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
import dev.inmo.tgbotapi.types.message.PrivateEventMessage
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@ -95,12 +94,11 @@ suspend fun <BC : BehaviourContext> BC.onChatEvent(
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data * data
*/ */
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent( suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null, initialFilter: SimpleFilter<ChatEventMessage<VoiceChatEvent>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEvent>, Update>? = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatEvent>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEvent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatEvent>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEvent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatEvent>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/** /**
@ -115,12 +113,11 @@ suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent(
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data * data
*/ */
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent( suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null, initialFilter: SimpleFilter<ChatEventMessage<VoiceChatStarted>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatStarted>, Update>? = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatStarted>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatStarted>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatStarted>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatStarted>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatStarted>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/** /**
@ -135,12 +132,11 @@ suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent(
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data * data
*/ */
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent( suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null, initialFilter: SimpleFilter<ChatEventMessage<VoiceChatEnded>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEnded>, Update>? = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatEnded>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEnded>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatEnded>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEnded>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatEnded>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/** /**
@ -155,88 +151,11 @@ suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent(
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data * data
*/ */
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatParticipantsInvitedEvent( suspend fun <BC : BehaviourContext> BC.onVoiceChatParticipantsInvitedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null, initialFilter: SimpleFilter<ChatEventMessage<VoiceChatParticipantsInvited>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatParticipantsInvited>, Update>? = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatParticipantsInvited>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatParticipantsInvited>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatParticipantsInvited>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onVideoChatEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEvent>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEvent>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEvent>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onVideoChatStartedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatStarted>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatStarted>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatStarted>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onVideoChatEndedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEnded>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEnded>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEnded>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onVideoChatParticipantsInvitedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatParticipantsInvited>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatParticipantsInvited>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/** /**
@ -564,30 +483,3 @@ suspend fun <BC : BehaviourContext> BC.onUserLoggedIn(
markerFactory: MarkerFactory<in ChatEventMessage<UserLoggedIn>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<UserLoggedIn>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<UserLoggedIn>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<UserLoggedIn>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param markerFactory Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onWebAppData(
initialFilter: SimpleFilter<PrivateEventMessage<WebAppData>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<WebAppData>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<WebAppData>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PrivateEventMessage<WebAppData>>
) = onEvent(
initialFilter ?.let { { it is PrivateEventMessage<WebAppData> && initialFilter(it) } },
subcontextUpdatesFilter ?.let { { it: ChatEventMessage<WebAppData>, update: Update -> it is PrivateEventMessage<WebAppData> && subcontextUpdatesFilter(it, update) } },
markerFactory
) {
if (it is PrivateEventMessage<WebAppData>) {
scenarioReceiver(it)
}
}

View File

@ -2,6 +2,6 @@ package dev.inmo.tgbotapi.CommonAbstracts.types
import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.ChatIdentifier
interface ChatRequest : OptionalChatRequest { interface ChatRequest {
override val chatId: ChatIdentifier val chatId: ChatIdentifier
} }

View File

@ -1,7 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts.types
import dev.inmo.tgbotapi.types.ChatIdentifier
interface OptionalChatRequest {
val chatId: ChatIdentifier?
}

View File

@ -16,6 +16,33 @@ import io.ktor.client.features.*
import io.ktor.client.statement.readText import io.ktor.client.statement.readText
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
class KtorRequestsExecutorBuilder(
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
) {
var client: HttpClient = HttpClient()
var callsFactories: List<KtorCallFactory> = emptyList()
var excludeDefaultFactories: Boolean = false
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
var jsonFormatter: Json = nonstrictJsonFormat
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
}
inline fun telegramBot(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
/**
* Shortcut for [telegramBot]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun telegramBot(
token: String,
apiUrl: String = telegramBotAPIDefaultUrl,
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
@RiskFeature @RiskFeature
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf( fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
SimpleRequestCallFactory(), SimpleRequestCallFactory(),
@ -100,30 +127,3 @@ class KtorRequestsExecutor(
client.close() client.close()
} }
} }
class KtorRequestsExecutorBuilder(
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
) {
var client: HttpClient = HttpClient()
var callsFactories: List<KtorCallFactory> = emptyList()
var excludeDefaultFactories: Boolean = false
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
var jsonFormatter: Json = nonstrictJsonFormat
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
}
inline fun telegramBot(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
/**
* Shortcut for [telegramBot]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun telegramBot(
token: String,
apiUrl: String = telegramBotAPIDefaultUrl,
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)

View File

@ -1,21 +0,0 @@
package dev.inmo.tgbotapi.requests.answers
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
import dev.inmo.tgbotapi.types.webapps.query.SentWebAppMessage
import kotlinx.serialization.*
@Serializable
data class AnswerWebAppQuery(
@SerialName(webAppQueryIdField)
val webAppQueryId: WebAppQueryId,
@SerialName(resultField)
val result: InlineQueryResult
) : SimpleRequest<SentWebAppMessage> {
override fun method(): String = "answerWebAppQuery"
override val resultDeserializer: DeserializationStrategy<SentWebAppMessage>
get() = SentWebAppMessage.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -1,18 +0,0 @@
package dev.inmo.tgbotapi.requests.bot
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
class ClearMyDefaultAdministratorRights(
@SerialName(forChannelsField)
val forChannels: Boolean? = null
) : SimpleRequest<Boolean> {
override fun method(): String = "setMyDefaultAdministratorRights"
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -1,23 +0,0 @@
package dev.inmo.tgbotapi.requests.bot
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.ChatMember.AdministratorChatMemberImpl
import kotlinx.serialization.*
@Serializable
data class GetMyDefaultAdministratorRights(
@SerialName(forChannelsField)
val forChannels: Boolean? = null
) : SimpleRequest<AdministratorChatMemberImpl> {
override fun method(): String = "getMyDefaultAdministratorRights"
override val resultDeserializer: DeserializationStrategy<AdministratorChatMemberImpl>
get() = AdministratorChatMemberImpl.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
companion object {
val ForChannels = GetMyDefaultAdministratorRights(true)
val ForGroups = GetMyDefaultAdministratorRights(false)
}
}

View File

@ -1,20 +0,0 @@
package dev.inmo.tgbotapi.requests.bot
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
class SetMyDefaultAdministratorRights(
@SerialName(rightsField)
val rights: ChatAdministratorRightsImpl,
@SerialName(forChannelsField)
val forChannels: Boolean? = null
) : SimpleRequest<Boolean> {
override fun method(): String = "setMyDefaultAdministratorRights"
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -1,21 +0,0 @@
package dev.inmo.tgbotapi.requests.chat.get
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
data class GetChatMenuButton(
@SerialName(chatIdField)
override val chatId: ChatIdentifier
) : ChatRequest, SimpleRequest<MenuButton> {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = GetDefaultChatMenuButton.method()
override val resultDeserializer: DeserializationStrategy<MenuButton>
get() = MenuButtonSerializer
}

View File

@ -1,21 +0,0 @@
package dev.inmo.tgbotapi.requests.chat.get
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
import dev.inmo.tgbotapi.CommonAbstracts.types.OptionalChatRequest
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
object GetDefaultChatMenuButton : OptionalChatRequest, SimpleRequest<MenuButton> {
override val chatId: ChatIdentifier?
get() = null
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = "getChatMenuButton"
override val resultDeserializer: DeserializationStrategy<MenuButton>
get() = MenuButtonSerializer
}

View File

@ -32,8 +32,8 @@ data class PromoteChatMember(
private val canPinMessages: Boolean? = null, private val canPinMessages: Boolean? = null,
@SerialName(canPromoteMembersField) @SerialName(canPromoteMembersField)
private val canPromoteMembers: Boolean? = null, private val canPromoteMembers: Boolean? = null,
@SerialName(canManageVideoChatsField) @SerialName(canManageVoiceChatsField)
private val canManageVideoChats: Boolean? = null, private val canManageVoiceChats: Boolean? = null,
@SerialName(canManageChatField) @SerialName(canManageChatField)
private val canManageChat: Boolean? = null private val canManageChat: Boolean? = null
) : ChatMemberRequest<Boolean>, UntilDate { ) : ChatMemberRequest<Boolean>, UntilDate {

View File

@ -1,24 +0,0 @@
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.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
data class SetChatMenuButton(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@Serializable(MenuButtonSerializer::class)
@SerialName(menuButtonField)
val menuButton: MenuButton
) : ChatRequest, SimpleRequest<Boolean> {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = SetDefaultChatMenuButton.method()
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
}

View File

@ -1,25 +0,0 @@
package dev.inmo.tgbotapi.requests.chat.modify
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@Serializable
data class SetDefaultChatMenuButton(
@Serializable(MenuButtonSerializer::class)
@SerialName(menuButtonField)
val menuButton: MenuButton
) : SimpleRequest<Boolean> {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = Companion.method()
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
companion object {
fun method() = "setChatMenuButton"
}
}

View File

@ -1,31 +0,0 @@
package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatAdministratorRights
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ChatAdministratorRightsImpl(
@SerialName(canChangeInfoField)
override val canChangeInfo: Boolean = false,
@SerialName(canPostMessagesField)
override val canPostMessages: Boolean = false,
@SerialName(canEditMessagesField)
override val canEditMessages: Boolean = false,
@SerialName(canDeleteMessagesField)
override val canRemoveMessages: Boolean = false,
@SerialName(canInviteUsersField)
override val canInviteUsers: Boolean = false,
@SerialName(canRestrictMembersField)
override val canRestrictMembers: Boolean = false,
@SerialName(canPinMessagesField)
override val canPinMessages: Boolean = false,
@SerialName(canPromoteMembersField)
override val canPromoteMembers: Boolean = false,
@SerialName(canManageVideoChatsField)
override val canManageVideoChats: Boolean = false,
@SerialName(canManageChatField)
override val canManageChat: Boolean = false,
@SerialName(isAnonymousField)
override val isAnonymous: Boolean = false
) : ChatAdministratorRights

View File

@ -26,8 +26,8 @@ data class AdministratorChatMemberImpl(
override val canPinMessages: Boolean = false, override val canPinMessages: Boolean = false,
@SerialName(canPromoteMembersField) @SerialName(canPromoteMembersField)
override val canPromoteMembers: Boolean = false, override val canPromoteMembers: Boolean = false,
@SerialName(canManageVideoChatsField) @SerialName(canManageVoiceChatsField)
override val canManageVideoChats: Boolean = false, override val canManageVoiceChats: Boolean = false,
@SerialName(canManageChatField) @SerialName(canManageChatField)
override val canManageChat: Boolean = false, override val canManageChat: Boolean = false,
@SerialName(isAnonymousField) @SerialName(isAnonymousField)

View File

@ -31,7 +31,7 @@ data class CreatorChatMember(
@Transient @Transient
override val canPromoteMembers: Boolean = true override val canPromoteMembers: Boolean = true
@Transient @Transient
override val canManageVideoChats: Boolean = true override val canManageVoiceChats: Boolean = true
@Transient @Transient
override val canManageChat: Boolean = true override val canManageChat: Boolean = true
@SerialName(statusField) @SerialName(statusField)

View File

@ -8,12 +8,17 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@Serializable(AdministratorChatMemberSerializer::class) @Serializable(AdministratorChatMemberSerializer::class)
interface AdministratorChatMember : SpecialRightsChatMember, ChatAdministratorRights { interface AdministratorChatMember : SpecialRightsChatMember {
val canBeEdited: Boolean val canBeEdited: Boolean
val customTitle: String? val canPostMessages: Boolean
val canEditMessages: Boolean
val canRemoveMessages: Boolean
val canRestrictMembers: Boolean
val canPromoteMembers: Boolean
val canManageVoiceChats: Boolean val canManageVoiceChats: Boolean
get() = canManageVideoChats val canManageChat: Boolean
val isAnonymous: Boolean
val customTitle: String?
} }
@RiskFeature @RiskFeature

View File

@ -1,18 +0,0 @@
package dev.inmo.tgbotapi.types.ChatMember.abstracts
sealed interface SpecialChatAdministratorRights {
val canChangeInfo: Boolean
val canInviteUsers: Boolean
val canPinMessages: Boolean
}
interface ChatAdministratorRights : SpecialChatAdministratorRights {
val isAnonymous: Boolean
val canManageChat: Boolean
val canRemoveMessages: Boolean
val canManageVideoChats: Boolean
val canRestrictMembers: Boolean
val canPromoteMembers: Boolean
val canPostMessages: Boolean
val canEditMessages: Boolean
}

View File

@ -3,4 +3,8 @@ package dev.inmo.tgbotapi.types.ChatMember.abstracts
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable(ChatMemberSerializer::class) @Serializable(ChatMemberSerializer::class)
interface SpecialRightsChatMember : ChatMember, SpecialChatAdministratorRights interface SpecialRightsChatMember : ChatMember {
val canChangeInfo: Boolean
val canInviteUsers: Boolean
val canPinMessages: Boolean
}

View File

@ -27,7 +27,6 @@ typealias FoursquareType = String
typealias GooglePlaceId = String typealias GooglePlaceId = String
typealias GooglePlaceType = String typealias GooglePlaceType = String
typealias MembersLimit = Int typealias MembersLimit = Int
typealias WebAppQueryId = String
typealias Seconds = Int typealias Seconds = Int
typealias MilliSeconds = Long typealias MilliSeconds = Long
@ -134,7 +133,6 @@ const val inlineMessageIdField = "inline_message_id"
const val callbackDataField = "callback_data" const val callbackDataField = "callback_data"
const val callbackGameField = "callback_game" const val callbackGameField = "callback_game"
const val callbackQueryIdField = "callback_query_id" const val callbackQueryIdField = "callback_query_id"
const val webAppQueryIdField = "web_app_query_id"
const val inlineQueryIdField = "inline_query_id" const val inlineQueryIdField = "inline_query_id"
const val inlineKeyboardField = "inline_keyboard" const val inlineKeyboardField = "inline_keyboard"
const val showAlertField = "show_alert" const val showAlertField = "show_alert"
@ -156,7 +154,6 @@ const val dropPendingUpdatesField = "drop_pending_updates"
const val hasCustomCertificateField = "has_custom_certificate" const val hasCustomCertificateField = "has_custom_certificate"
const val pendingUpdateCountField = "pending_update_count" const val pendingUpdateCountField = "pending_update_count"
const val lastErrorDateField = "last_error_date" const val lastErrorDateField = "last_error_date"
const val lastSynchronizationErrorDateField = "last_synchronization_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"
@ -266,9 +263,6 @@ const val canRestrictMembersField = "can_restrict_members"
const val canPinMessagesField = "can_pin_messages" const val canPinMessagesField = "can_pin_messages"
const val canPromoteMembersField = "can_promote_members" const val canPromoteMembersField = "can_promote_members"
const val canManageVoiceChatsField = "can_manage_voice_chats" const val canManageVoiceChatsField = "can_manage_voice_chats"
const val canManageVideoChatsField = "can_manage_video_chats"
const val rightsField = "rights"
const val forChannelsField = "for_channels"
const val canManageChatField = "can_manage_chat" const val canManageChatField = "can_manage_chat"
const val pngStickerField = "png_sticker" const val pngStickerField = "png_sticker"
const val tgsStickerField = "tgs_sticker" const val tgsStickerField = "tgs_sticker"
@ -319,7 +313,6 @@ const val pricesField = "prices"
const val payloadField = "payload" const val payloadField = "payload"
const val vcardField = "vcard" const val vcardField = "vcard"
const val resultsField = "results" const val resultsField = "results"
const val resultField = "result"
const val certificateField = "certificate" const val certificateField = "certificate"
const val questionField = "question" const val questionField = "question"
const val optionsField = "options" const val optionsField = "options"
@ -437,7 +430,3 @@ const val bankStatementField = "bank_statement"
const val rentalAgreementField = "rental_agreement" const val rentalAgreementField = "rental_agreement"
const val passportRegistrationField = "passport_registration" const val passportRegistrationField = "passport_registration"
const val temporaryRegistrationField = "temporary_registration" const val temporaryRegistrationField = "temporary_registration"
const val buttonTextField = "button_text"
const val webAppField = "web_app"
const val menuButtonField = "menu_button"

View File

@ -1,122 +0,0 @@
package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
@Serializable(MenuButtonSerializer::class)
sealed interface MenuButton {
@Required
val type: String
@Serializable
object Commands : MenuButton {
@Required
override val type: String
get() = "commands"
}
@Serializable
data class WebApp(
val text: String,
@SerialName(webAppField)
val webApp: WebAppInfo
) : MenuButton {
@Required
override val type: String
get() = Companion.type
companion object {
val type: String
get() = "web_app"
}
}
@Serializable
object Default : MenuButton {
@Required
override val type: String
get() = "default"
}
@Serializable
@RiskFeature
data class Unknown (
override val type: String,
val rawJson: JsonElement
) : MenuButton
companion object {
fun serializer(): KSerializer<MenuButton> = MenuButtonSerializer
}
}
@Serializable
internal data class MenuButtonSurrogate(
val type: String,
val text: String? = null,
@SerialName(webAppField)
val webApp: WebAppInfo? = null,
val srcJsonElement: JsonElement? = null
)
@Serializer(MenuButton::class)
object MenuButtonSerializer : KSerializer<MenuButton> {
override val descriptor: SerialDescriptor
get() = MenuButtonSurrogate.serializer().descriptor
override fun deserialize(decoder: Decoder): MenuButton {
val surrogate = if (decoder is JsonDecoder) {
val json = JsonElement.serializer().deserialize(decoder)
runCatching {
decoder.json.decodeFromJsonElement(MenuButtonSurrogate.serializer(), json)
}.onFailure {
return MenuButton.Unknown(
runCatching { json.jsonObject[typeField] ?.jsonPrimitive ?.content }.getOrNull() ?: "",
json
)
}.getOrThrow().copy(
srcJsonElement = json
)
} else {
MenuButtonSurrogate.serializer().deserialize(decoder)
}
return when (surrogate.type) {
MenuButton.Commands.type -> MenuButton.Commands
MenuButton.Default.type -> MenuButton.Default
MenuButton.WebApp.type -> if (surrogate.text != null && surrogate.webApp != null) {
MenuButton.WebApp(surrogate.text, surrogate.webApp)
} else {
null
}
else -> null
} ?: MenuButton.Unknown(
surrogate.type,
surrogate.srcJsonElement ?: buildJsonObject { }
)
}
override fun serialize(encoder: Encoder, value: MenuButton) {
encoder.encodeSerializableValue(
MenuButtonSurrogate.serializer(),
when (value) {
MenuButton.Default,
MenuButton.Commands -> MenuButtonSurrogate(value.type)
is MenuButton.WebApp -> MenuButtonSurrogate(value.type, value.text, value.webApp)
is MenuButton.Unknown -> {
encoder.encodeSerializableValue(
JsonElement.serializer(),
value.rawJson
)
return
}
}
)
}
}

View File

@ -16,8 +16,6 @@ data class WebhookInfo(
val allowedUpdates: List<String> = ALL_UPDATES_LIST, val allowedUpdates: List<String> = ALL_UPDATES_LIST,
@SerialName(lastErrorDateField) @SerialName(lastErrorDateField)
val lastErrorDate: TelegramDate? = null, val lastErrorDate: TelegramDate? = null,
@SerialName(lastSynchronizationErrorDateField)
val lastSynchronizationErrorDate: TelegramDate? = null,
@SerialName(lastErrorMessageField) @SerialName(lastErrorMessageField)
val lastErrorMessage: String? = null val lastErrorMessage: String? = null
) { ) {

View File

@ -2,9 +2,8 @@ package dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.games.CallbackGame import dev.inmo.tgbotapi.types.games.CallbackGame
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.json.* import kotlinx.serialization.json.JsonElement
/** /**
* Some button of [dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup]. See inheritors and visit * Some button of [dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup]. See inheritors and visit
@ -16,14 +15,10 @@ sealed interface InlineKeyboardButton {
} }
@Serializable @Serializable
data class UnknownInlineKeyboardButton ( data class UnknownInlineKeyboardButton internal constructor(
override val text: String,
val rawData: JsonElement val rawData: JsonElement
) : InlineKeyboardButton { ) : InlineKeyboardButton
override val text: String
get() = runCatching {
rawData.jsonObject[textField] ?.jsonPrimitive ?.content
}.getOrNull() ?: ""
}
/** /**
* This type of button must always be the first button in the first row. Visit * This type of button must always be the first button in the first row. Visit
@ -121,14 +116,3 @@ data class URLInlineKeyboardButton(
@SerialName(urlField) @SerialName(urlField)
val url: String val url: String
) : InlineKeyboardButton ) : 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

View File

@ -37,7 +37,7 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
return (json as? JsonObject) ?.let { resolveSerializer(it) } ?.let { return (json as? JsonObject) ?.let { resolveSerializer(it) } ?.let {
nonstrictJsonFormat.decodeFromJsonElement(it, json) nonstrictJsonFormat.decodeFromJsonElement(it, json)
} ?: UnknownInlineKeyboardButton(json) } ?: UnknownInlineKeyboardButton("", json)
} }
override fun serialize(encoder: Encoder, value: InlineKeyboardButton) { override fun serialize(encoder: Encoder, value: InlineKeyboardButton) {
@ -48,7 +48,6 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value) is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value)
is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value) is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value)
is URLInlineKeyboardButton -> URLInlineKeyboardButton.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 CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value)
is UnknownInlineKeyboardButton -> JsonElement.serializer().serialize(encoder, value.rawData) is UnknownInlineKeyboardButton -> JsonElement.serializer().serialize(encoder, value.rawData)
} }

View File

@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.buttons package dev.inmo.tgbotapi.types.buttons
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.* import kotlinx.serialization.*
@ -64,22 +63,10 @@ data class RequestLocationKeyboardButton(
override val text: String override val text: String
) : KeyboardButton { ) : KeyboardButton {
@SerialName(requestLocationField) @SerialName(requestLocationField)
@Required @EncodeDefault
val requestLocation: Boolean = true 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 * 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 * to catch this poll in updates and data using [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPoll] in
@ -110,13 +97,6 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton( asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton(
asJson[textField]!!.jsonPrimitive.content 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 is JsonObject && asJson[requestPollField] != null -> RequestPollKeyboardButton(
asJson[textField]!!.jsonPrimitive.content, asJson[textField]!!.jsonPrimitive.content,
nonstrictJsonFormat.decodeFromJsonElement( nonstrictJsonFormat.decodeFromJsonElement(
@ -139,7 +119,6 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
when (value) { when (value) {
is RequestContactKeyboardButton -> RequestContactKeyboardButton.serializer().serialize(encoder, value) is RequestContactKeyboardButton -> RequestContactKeyboardButton.serializer().serialize(encoder, value)
is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.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 RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
is SimpleKeyboardButton -> encoder.encodeString(value.text) is SimpleKeyboardButton -> encoder.encodeString(value.text)
is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw)) is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw))

View File

@ -1,15 +0,0 @@
package dev.inmo.tgbotapi.types.message.ChatEvents
import dev.inmo.tgbotapi.types.buttonTextField
import dev.inmo.tgbotapi.types.dataField
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class WebAppData(
@SerialName(dataField)
val data: String,
@SerialName(buttonTextField)
val buttonText: String
) : PrivateEvent

View File

@ -1,8 +0,0 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatScheduled
interface VideoChatEvent : PublicChatEvent
@Deprecated("Renamed", ReplaceWith("VideoChatEvent", "dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatEvent"))
typealias VoiceChatEvent = VideoChatEvent

View File

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

View File

@ -1,16 +0,0 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent
import dev.inmo.tgbotapi.types.usersField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class VideoChatParticipantsInvited(
@SerialName(usersField)
val users: List<User> = emptyList()
) : VideoChatEvent
@Deprecated("Renamed", ReplaceWith("VideoChatParticipantsInvited", "dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatParticipantsInvited"))
typealias VoiceChatParticipantsInvited = VideoChatParticipantsInvited

View File

@ -1,10 +0,0 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent
import kotlinx.serialization.Serializable
@Serializable
object VideoChatStarted : VideoChatEvent
@Deprecated("Renamed", ReplaceWith("VideoChatStarted", "dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatStarted"))
typealias VoiceChatStarted = VideoChatStarted

View File

@ -4,18 +4,15 @@ import com.soywiz.klock.TimeSpan
import com.soywiz.klock.seconds import com.soywiz.klock.seconds
import dev.inmo.tgbotapi.types.Seconds import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.durationField import dev.inmo.tgbotapi.types.durationField
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class VideoChatEnded( data class VoiceChatEnded(
@SerialName(durationField) @SerialName(durationField)
val duration: Seconds val duration: Seconds
) : VideoChatEvent { ) : VoiceChatEvent {
val timeSpan: TimeSpan val timeSpan: TimeSpan
get() = TimeSpan(duration.seconds.milliseconds) get() = TimeSpan(duration.seconds.milliseconds)
} }
@Deprecated("Renamed", ReplaceWith("VideoChatEnded", "dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatEnded"))
typealias VoiceChatEnded = VideoChatEnded

View File

@ -0,0 +1,13 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import dev.inmo.tgbotapi.types.usersField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class VoiceChatParticipantsInvited(
@SerialName(usersField)
val users: List<User> = emptyList()
) : VoiceChatEvent

View File

@ -1,16 +1,13 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.TelegramDate import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import dev.inmo.tgbotapi.types.startDateField import dev.inmo.tgbotapi.types.startDateField
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class VideoChatScheduled( data class VoiceChatScheduled(
@SerialName(startDateField) @SerialName(startDateField)
val startDate: TelegramDate val startDate: TelegramDate
) : VideoChatEvent ) : VoiceChatEvent
@Deprecated("Renamed", ReplaceWith("VideoChatScheduled", "dev.inmo.tgbotapi.types.message.ChatEvents.voice.VideoChatScheduled"))
typealias VoiceChatScheduled = VideoChatScheduled

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import kotlinx.serialization.Serializable
@Serializable
object VoiceChatStarted : VoiceChatEvent

View File

@ -84,10 +84,10 @@ internal data class RawMessage(
private val successful_payment: SuccessfulPayment? = null, private val successful_payment: SuccessfulPayment? = null,
// Voice Chat Service Messages // Voice Chat Service Messages
private val video_chat_scheduled: VideoChatScheduled? = null, private val voice_chat_scheduled: VoiceChatScheduled? = null,
private val video_chat_started: VideoChatStarted? = null, private val voice_chat_started: VoiceChatStarted? = null,
private val video_chat_ended: VideoChatEnded? = null, private val voice_chat_ended: VoiceChatEnded? = null,
private val video_chat_participants_invited: VideoChatParticipantsInvited? = null, private val voice_chat_participants_invited: VoiceChatParticipantsInvited? = null,
// AutoDelete Message time changed // AutoDelete Message time changed
private val message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? = null, private val message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? = null,
@ -95,9 +95,6 @@ internal data class RawMessage(
// login property // login property
private val connected_website: String? = null, private val connected_website: String? = null,
// login property
private val web_app_data: WebAppData? = null,
// passport property // passport property
private val passport_data: PassportData? = null, private val passport_data: PassportData? = null,
private val proximity_alert_triggered: ProximityAlertTriggered? = null, private val proximity_alert_triggered: ProximityAlertTriggered? = null,
@ -186,11 +183,11 @@ internal data class RawMessage(
left_chat_member != null -> LeftChatMember(left_chat_member) left_chat_member != null -> LeftChatMember(left_chat_member)
new_chat_title != null -> NewChatTitle(new_chat_title) new_chat_title != null -> NewChatTitle(new_chat_title)
new_chat_photo != null -> NewChatPhoto(new_chat_photo.toList()) new_chat_photo != null -> NewChatPhoto(new_chat_photo.toList())
video_chat_started != null -> video_chat_started voice_chat_started != null -> voice_chat_started
video_chat_scheduled != null -> video_chat_scheduled voice_chat_scheduled != null -> voice_chat_scheduled
message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed
video_chat_ended != null -> video_chat_ended voice_chat_ended != null -> voice_chat_ended
video_chat_participants_invited != null -> video_chat_participants_invited voice_chat_participants_invited != null -> voice_chat_participants_invited
delete_chat_photo -> DeleteChatPhoto() delete_chat_photo -> DeleteChatPhoto()
group_chat_created -> GroupChatCreated( group_chat_created -> GroupChatCreated(
migrate_to_chat_id migrate_to_chat_id
@ -206,7 +203,6 @@ internal data class RawMessage(
proximity_alert_triggered != null -> proximity_alert_triggered proximity_alert_triggered != null -> proximity_alert_triggered
successful_payment != null -> SuccessfulPaymentEvent(successful_payment) successful_payment != null -> SuccessfulPaymentEvent(successful_payment)
connected_website != null -> UserLoggedIn(connected_website) connected_website != null -> UserLoggedIn(connected_website)
web_app_data != null -> web_app_data
else -> null else -> null
} }
} }

View File

@ -1,11 +0,0 @@
package dev.inmo.tgbotapi.types.webapps
import dev.inmo.tgbotapi.types.urlField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class WebAppInfo(
@SerialName(urlField)
val url: String
)

View File

@ -1,9 +0,0 @@
package dev.inmo.tgbotapi.types.webapps.query
import dev.inmo.tgbotapi.types.InlineMessageIdentifier
import kotlinx.serialization.Serializable
@Serializable
data class SentWebAppMessage(
val inlineMessageId: InlineMessageIdentifier? = null
)

View File

@ -2516,16 +2516,6 @@ inline fun InlineKeyboardButton.asURLInlineKeyboardButton(): URLInlineKeyboardBu
inline fun InlineKeyboardButton.requireURLInlineKeyboardButton(): URLInlineKeyboardButton = inline fun InlineKeyboardButton.requireURLInlineKeyboardButton(): URLInlineKeyboardButton =
this as URLInlineKeyboardButton this as URLInlineKeyboardButton
@PreviewFeature
inline fun <T> 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 @PreviewFeature
inline fun <T> InlineKeyboardButton.whenUnknownInlineKeyboardButton(block: (UnknownInlineKeyboardButton) -> T) = asUnknownInlineKeyboardButton() ?.let(block) inline fun <T> InlineKeyboardButton.whenUnknownInlineKeyboardButton(block: (UnknownInlineKeyboardButton) -> T) = asUnknownInlineKeyboardButton() ?.let(block)
@ -3201,113 +3191,51 @@ inline fun ChatEvent.asSupergroupEvent(): SupergroupEvent? = this as? Supergroup
inline fun ChatEvent.requireSupergroupEvent(): SupergroupEvent = this as SupergroupEvent inline fun ChatEvent.requireSupergroupEvent(): SupergroupEvent = this as SupergroupEvent
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun <T> ChatEvent.whenVoiceChatEvent(block: (VoiceChatEvent) -> T) = asVoiceChatEvent() ?.let(block)
inline fun <T> ChatEvent.whenVoiceChatEvent(block: (VideoChatEvent) -> T) = asVoiceChatEvent() ?.let(block)
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.asVoiceChatEvent(): VoiceChatEvent? = this as? VoiceChatEvent
inline fun ChatEvent.asVoiceChatEvent(): VideoChatEvent? = this as? VideoChatEvent
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.requireVoiceChatEvent(): VoiceChatEvent = this as VoiceChatEvent
inline fun ChatEvent.requireVoiceChatEvent(): VideoChatEvent = this as VideoChatEvent
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun <T> ChatEvent.whenVoiceChatEnded(block: (VoiceChatEnded) -> T) = asVoiceChatEnded() ?.let(block)
inline fun <T> ChatEvent.whenVoiceChatEnded(block: (VideoChatEnded) -> T) = asVoiceChatEnded() ?.let(block)
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.asVoiceChatEnded(): VoiceChatEnded? = this as? VoiceChatEnded
inline fun ChatEvent.asVoiceChatEnded(): VideoChatEnded? = this as? VideoChatEnded
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.requireVoiceChatEnded(): VoiceChatEnded = this as VoiceChatEnded
inline fun ChatEvent.requireVoiceChatEnded(): VideoChatEnded = this as VideoChatEnded
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun <T> ChatEvent.whenVoiceChatParticipantsInvited(block: (VoiceChatParticipantsInvited) -> T) = asVoiceChatParticipantsInvited() ?.let(block)
inline fun <T> ChatEvent.whenVoiceChatParticipantsInvited(block: (VideoChatParticipantsInvited) -> T) = asVoiceChatParticipantsInvited() ?.let(block)
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.asVoiceChatParticipantsInvited(): VoiceChatParticipantsInvited? =
inline fun ChatEvent.asVoiceChatParticipantsInvited(): VideoChatParticipantsInvited? = this as? VoiceChatParticipantsInvited
this as? VideoChatParticipantsInvited
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.requireVoiceChatParticipantsInvited(): VoiceChatParticipantsInvited =
inline fun ChatEvent.requireVoiceChatParticipantsInvited(): VideoChatParticipantsInvited = this as VoiceChatParticipantsInvited
this as VideoChatParticipantsInvited
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun <T> ChatEvent.whenVoiceChatStarted(block: (VoiceChatStarted) -> T) = asVoiceChatStarted() ?.let(block)
inline fun <T> ChatEvent.whenVoiceChatStarted(block: (VideoChatStarted) -> T) = asVoiceChatStarted() ?.let(block)
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.asVoiceChatStarted(): VoiceChatStarted? = this as? VoiceChatStarted
inline fun ChatEvent.asVoiceChatStarted(): VideoChatStarted? = this as? VideoChatStarted
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.requireVoiceChatStarted(): VoiceChatStarted = this as VoiceChatStarted
inline fun ChatEvent.requireVoiceChatStarted(): VideoChatStarted = this as VideoChatStarted
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun <T> ChatEvent.whenVoiceChatScheduled(block: (VoiceChatScheduled) -> T) = asVoiceChatScheduled() ?.let(block)
inline fun <T> ChatEvent.whenVoiceChatScheduled(block: (VideoChatScheduled) -> T) = asVoiceChatScheduled() ?.let(block)
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.asVoiceChatScheduled(): VoiceChatScheduled? = this as? VoiceChatScheduled
inline fun ChatEvent.asVoiceChatScheduled(): VideoChatScheduled? = this as? VideoChatScheduled
@PreviewFeature @PreviewFeature
@Deprecated("Renamed as Video instead of Voice") inline fun ChatEvent.requireVoiceChatScheduled(): VoiceChatScheduled = this as VoiceChatScheduled
inline fun ChatEvent.requireVoiceChatScheduled(): VideoChatScheduled = this as VideoChatScheduled
@PreviewFeature
inline fun <T> ChatEvent.whenVideoChatEvent(block: (VideoChatEvent) -> T) = asVideoChatEvent() ?.let(block)
@PreviewFeature
inline fun ChatEvent.asVideoChatEvent(): VideoChatEvent? = this as? VideoChatEvent
@PreviewFeature
inline fun ChatEvent.requireVideoChatEvent(): VideoChatEvent = this as VideoChatEvent
@PreviewFeature
inline fun <T> ChatEvent.whenVideoChatEnded(block: (VideoChatEnded) -> T) = asVideoChatEnded() ?.let(block)
@PreviewFeature
inline fun ChatEvent.asVideoChatEnded(): VideoChatEnded? = this as? VideoChatEnded
@PreviewFeature
inline fun ChatEvent.requireVideoChatEnded(): VideoChatEnded = this as VideoChatEnded
@PreviewFeature
inline fun <T> ChatEvent.whenVideoChatParticipantsInvited(block: (VideoChatParticipantsInvited) -> T) = asVideoChatParticipantsInvited() ?.let(block)
@PreviewFeature
inline fun ChatEvent.asVideoChatParticipantsInvited(): VideoChatParticipantsInvited? =
this as? VideoChatParticipantsInvited
@PreviewFeature
inline fun ChatEvent.requireVideoChatParticipantsInvited(): VideoChatParticipantsInvited =
this as VideoChatParticipantsInvited
@PreviewFeature
inline fun <T> ChatEvent.whenVideoChatStarted(block: (VideoChatStarted) -> T) = asVideoChatStarted() ?.let(block)
@PreviewFeature
inline fun ChatEvent.asVideoChatStarted(): VideoChatStarted? = this as? VideoChatStarted
@PreviewFeature
inline fun ChatEvent.requireVideoChatStarted(): VideoChatStarted = this as VideoChatStarted
@PreviewFeature
inline fun <T> ChatEvent.whenVideoChatScheduled(block: (VideoChatScheduled) -> T) = asVideoChatScheduled() ?.let(block)
@PreviewFeature
inline fun ChatEvent.asVideoChatScheduled(): VideoChatScheduled? = this as? VideoChatScheduled
@PreviewFeature
inline fun ChatEvent.requireVideoChatScheduled(): VideoChatScheduled = this as VideoChatScheduled
@PreviewFeature @PreviewFeature
inline fun <T> ChatEvent.whenUserLoggedIn(block: (UserLoggedIn) -> T) = asUserLoggedIn() ?.let(block) inline fun <T> ChatEvent.whenUserLoggedIn(block: (UserLoggedIn) -> T) = asUserLoggedIn() ?.let(block)

View File

@ -177,33 +177,17 @@ inline val Message.successful_payment: SuccessfulPayment?
get() = asChatEventMessage() ?.chatEvent ?.asSuccessfulPaymentEvent() ?.payment get() = asChatEventMessage() ?.chatEvent ?.asSuccessfulPaymentEvent() ?.payment
@RiskFeature(RawFieldsUsageWarning) @RiskFeature(RawFieldsUsageWarning)
@Deprecated("Renamed as video instead of voice") inline val Message.voice_chat_scheduled: VoiceChatScheduled?
inline val Message.voice_chat_scheduled: VideoChatScheduled?
get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatScheduled() get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatScheduled()
@RiskFeature(RawFieldsUsageWarning) @RiskFeature(RawFieldsUsageWarning)
@Deprecated("Renamed as video instead of voice") inline val Message.voice_chat_started: VoiceChatStarted?
inline val Message.voice_chat_started: VideoChatStarted?
get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatStarted() get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatStarted()
@RiskFeature(RawFieldsUsageWarning) @RiskFeature(RawFieldsUsageWarning)
@Deprecated("Renamed as video instead of voice") inline val Message.voice_chat_ended: VoiceChatEnded?
inline val Message.voice_chat_ended: VideoChatEnded?
get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatEnded() get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatEnded()
@RiskFeature(RawFieldsUsageWarning) @RiskFeature(RawFieldsUsageWarning)
@Deprecated("Renamed as video instead of voice") inline val Message.voice_chat_participants_invited: VoiceChatParticipantsInvited?
inline val Message.voice_chat_participants_invited: VideoChatParticipantsInvited?
get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatParticipantsInvited() get() = asChatEventMessage() ?.chatEvent ?.asVoiceChatParticipantsInvited()
@RiskFeature(RawFieldsUsageWarning)
inline val Message.video_chat_scheduled: VideoChatScheduled?
get() = asChatEventMessage() ?.chatEvent ?.asVideoChatScheduled()
@RiskFeature(RawFieldsUsageWarning)
inline val Message.video_chat_started: VideoChatStarted?
get() = asChatEventMessage() ?.chatEvent ?.asVideoChatStarted()
@RiskFeature(RawFieldsUsageWarning)
inline val Message.video_chat_ended: VideoChatEnded?
get() = asChatEventMessage() ?.chatEvent ?.asVideoChatEnded()
@RiskFeature(RawFieldsUsageWarning)
inline val Message.video_chat_participants_invited: VideoChatParticipantsInvited?
get() = asChatEventMessage() ?.chatEvent ?.asVideoChatParticipantsInvited()
@RiskFeature(RawFieldsUsageWarning) @RiskFeature(RawFieldsUsageWarning)
inline val Message.message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? inline val Message.message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged?

View File

@ -3,7 +3,6 @@ package dev.inmo.tgbotapi.extensions.utils.types.buttons
import dev.inmo.tgbotapi.types.LoginURL import dev.inmo.tgbotapi.types.LoginURL
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.* import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup 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.MatrixBuilder
import dev.inmo.tgbotapi.utils.RowBuilder import dev.inmo.tgbotapi.utils.RowBuilder
@ -129,25 +128,3 @@ inline fun InlineKeyboardRowBuilder.urlButton(
text: String, text: String,
url: String url: String
) = add(URLInlineKeyboardButton(text, url)) ) = 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))
/**
* 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,
url: String
) = webAppButton(text, WebAppInfo(url))

View File

@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.extensions.utils.types.buttons package dev.inmo.tgbotapi.extensions.utils.types.buttons
import dev.inmo.tgbotapi.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.MatrixBuilder
import dev.inmo.tgbotapi.utils.RowBuilder import dev.inmo.tgbotapi.utils.RowBuilder
@ -99,14 +98,3 @@ inline fun ReplyKeyboardRowBuilder.requestPollButton(
text: String, text: String,
pollType: KeyboardButtonPollType pollType: KeyboardButtonPollType
) = add(RequestPollKeyboardButton(text, pollType)) ) = 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))

View File

@ -1,49 +0,0 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
project.version = "$library_version"
project.group = "$library_group"
project.description = "Web App bindings for the Telegram Web Apps API"
apply from: "../publish.gradle"
repositories {
mavenLocal()
mavenCentral()
}
kotlin {
js(IR) {
browser()
nodejs()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api project(":tgbotapi.core")
}
}
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@ -1,6 +0,0 @@
package dev.inmo.tgbotapi.webapps
enum class ColorScheme {
LIGHT,
DARK
}

View File

@ -1,7 +0,0 @@
package dev.inmo.tgbotapi.webapps
import dev.inmo.micro_utils.crypto.CryptoJs
fun CryptoJs.HmacSHA256(text: String, key: String) = this.asDynamic().HmacSHA256(text, key).unsafeCast<String>()
fun CryptoJs.hex(text: String) = this.asDynamic().format.Hex(text).unsafeCast<String>()

View File

@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.webapps
typealias EventHandler = WebApp.() -> Unit
typealias ViewportChangedEventHandler = WebApp.(ViewportChangedData) -> Unit

View File

@ -1,7 +0,0 @@
package dev.inmo.tgbotapi.webapps
sealed class EventType(val typeName: String) {
object ThemeChanged : EventType("themeChanged")
object ViewportChanged : EventType("viewportChanged")
object MainButtonClicked : EventType("mainButtonClicked")
}

View File

@ -1,55 +0,0 @@
package dev.inmo.tgbotapi.webapps
import kotlin.js.Json
import kotlin.js.json
external class MainButton {
val text: String
fun setText(text: String): MainButton
var color: String
var textColor: String
val isVisible: Boolean
fun show(): MainButton
fun hide(): MainButton
val isActive: Boolean
fun enable(): MainButton
fun disable(): MainButton
val isProgressVisible: Boolean
fun showProgress(leaveActive: Boolean = definedExternally): MainButton
fun hideProgress(): MainButton
internal fun onClick(eventHandler: () -> Unit): MainButton
internal fun setParams(params: Json): MainButton
}
data class MainButtonParams(
val text: String? = null,
val color: String? = null,
val textColor: String? = null,
val isActive: Boolean? = null,
val isVisible: Boolean? = null
)
fun MainButton.onClick(eventHandler: EventHandler) = onClick {
val that = js("this").unsafeCast<WebApp>()
that.eventHandler()
}
fun MainButton.setParams(params: MainButtonParams) = setParams(
json(
*listOfNotNull(
params.text ?.let { "text" to params.text },
params.color ?.let { "color" to params.color },
params.textColor ?.let { "text_color" to params.textColor },
params.isActive ?.let { "is_active" to params.isActive },
params.isVisible ?.let { "is_visible" to params.isVisible },
).toTypedArray()
)
)

View File

@ -1,17 +0,0 @@
package dev.inmo.tgbotapi.webapps
import kotlinx.browser.window
import org.w3c.dom.Window
external interface Telegram {
val WebApp: WebApp
}
val Window.Telegram
get() = asDynamic().Telegram.unsafeCast<Telegram>()
val telegram: Telegram
get() = window.Telegram
val webApp: WebApp
get() = telegram.WebApp

View File

@ -1,16 +0,0 @@
package dev.inmo.tgbotapi.webapps
external interface ThemeParams {
@JsName("bg_color")
val backgroundColor: String?
@JsName("text_color")
val textColor: String?
@JsName("hint_color")
val hintColor: String?
@JsName("link_color")
val linkColor: String?
@JsName("button_color")
val buttonColor: String?
@JsName("button_text_color")
val buttonTextColor: String?
}

View File

@ -1,5 +0,0 @@
package dev.inmo.tgbotapi.webapps
external interface ViewportChangedData {
val isStateStable: Boolean
}

View File

@ -1,81 +0,0 @@
package dev.inmo.tgbotapi.webapps
import dev.inmo.micro_utils.crypto.CryptoJS
external class WebApp {
val initData: String
val initDataUnsafe: WebAppInitData
@JsName("colorScheme")
val colorSchemeRaw: String
val themeParams: ThemeParams
val isExpanded: Boolean
val viewportHeight: Float
val viewportStableHeight: Float
@JsName("MainButton")
val mainButton: MainButton
internal fun onEvent(type: String, callback: () -> Unit)
@JsName("onEvent")
internal fun onEventWithBoolean(type: String, callback: (ViewportChangedData) -> Unit)
fun offEvent(type: String, callback: () -> Unit)
@JsName("offEvent")
fun offEventWithBoolean(type: String, callback: (ViewportChangedData) -> Unit)
fun sendData(data: String)
fun ready()
fun expand()
fun close()
}
val WebApp.colorScheme: ColorScheme
get() = when (colorSchemeRaw) {
"light" -> ColorScheme.LIGHT
"dark" -> ColorScheme.DARK
else -> ColorScheme.LIGHT
}
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.onEvent(type: EventType, eventHandler: EventHandler) = {
eventHandler(js("this").unsafeCast<WebApp>())
}.also {
onEvent(
type.typeName,
callback = it
)
}
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.onEvent(type: EventType.ViewportChanged, eventHandler: ViewportChangedEventHandler) = { it: ViewportChangedData ->
eventHandler(js("this").unsafeCast<WebApp>(), it)
}.also {
onEventWithBoolean(
type.typeName,
callback = it
)
}
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.onThemeChanged(eventHandler: EventHandler) = onEvent(EventType.ThemeChanged, eventHandler)
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.onMainButtonClicked(eventHandler: EventHandler) = onEvent(EventType.MainButtonClicked, eventHandler)
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.onViewportChanged(eventHandler: ViewportChangedEventHandler) = onEvent(EventType.ViewportChanged, eventHandler)
fun WebApp.isInitDataSafe(botToken: String) = CryptoJS.hex(
CryptoJS.HmacSHA256(botToken, "WebAppData")
) == initDataUnsafe.hash

View File

@ -1,19 +0,0 @@
package dev.inmo.tgbotapi.webapps
import dev.inmo.tgbotapi.types.MilliSeconds
import dev.inmo.tgbotapi.types.WebAppQueryId
external interface WebAppInitData {
val queryId: WebAppQueryId?
val user: WebAppUser?
val receiver: WebAppUser?
@JsName("start_param")
val startParam: String?
@JsName("auth_date")
val authDate: MilliSeconds
val hash: String
}

View File

@ -1,37 +0,0 @@
package dev.inmo.tgbotapi.webapps
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
import dev.inmo.tgbotapi.types.*
external interface WebAppUser {
val id: Identifier
@JsName(isBotField)
val isBot: Boolean?
@JsName(firstNameField)
val firstName: String
@JsName(lastNameField)
val lastName: String?
@JsName(usernameField)
val username: String?
@JsName(languageCodeField)
val languageCode: String?
@JsName(photoUrlField)
val photoUrl: String?
}
fun WebAppUser.asUser() = if (isBot == true) {
CommonBot(
UserId(id),
username ?.let(::Username) ?: error("Username is absent for bot, but must exists"),
firstName,
lastName ?: ""
)
} else {
CommonUser(
UserId(id),
firstName,
lastName ?: "",
username ?.let(::Username),
languageCode ?.let(::IetfLanguageCode)
)
}