1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2026-01-05 21:09:29 +00:00

Compare commits

...

5 Commits

27 changed files with 325 additions and 36 deletions

View File

@@ -16,6 +16,9 @@ kotlin {
api project(":tgbotapi.core") api project(":tgbotapi.core")
} }
} }
configureEach {
languageSettings.optIn("kotlinx.serialization.ExperimentalSerializationApi")
}
} }
} }

View File

@@ -4,6 +4,8 @@ import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.DeleteMessages import dev.inmo.tgbotapi.requests.DeleteMessages
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import kotlin.jvm.JvmName
suspend fun TelegramBot.deleteMessages( suspend fun TelegramBot.deleteMessages(
chatId: ChatIdentifier, chatId: ChatIdentifier,
@@ -35,14 +37,19 @@ suspend fun TelegramBot.deleteMessages(
) )
suspend fun TelegramBot.deleteMessages( suspend fun TelegramBot.deleteMessages(
messages: List<AccessibleMessage> messagesMetas: List<Message.MetaInfo>
) = messages.groupBy { it.chat }.map { (chat, messages) -> ) = messagesMetas.groupBy { it.chatId }.map { (chatId, messages) ->
deleteMessages( deleteMessages(
chatId = chat.id, chatId = chatId,
messageIds = messages.map { it.messageId } messageIds = messages.map { it.messageId }
) )
}.all { it } }.all { it }
@JvmName("deleteMessagesWithMessages")
suspend fun TelegramBot.deleteMessages(
messages: List<AccessibleMessage>
) = deleteMessages(messages.map { it.metaInfo })
suspend fun TelegramBot.delete( suspend fun TelegramBot.delete(
chatId: ChatIdentifier, chatId: ChatIdentifier,
messageIds: List<MessageId> messageIds: List<MessageId>
@@ -60,6 +67,12 @@ suspend fun TelegramBot.delete(
vararg messageIds: MessageId vararg messageIds: MessageId
) = deleteMessages(chatId = chatId, messageIds = (listOf(firstMessageId, secondMessageId) + messageIds.toList())) ) = deleteMessages(chatId = chatId, messageIds = (listOf(firstMessageId, secondMessageId) + messageIds.toList()))
suspend fun TelegramBot.delete(
messagesMetas: List<Message.MetaInfo>
) = deleteMessages(messagesMetas)
@JvmName("deleteWithMessages")
suspend fun TelegramBot.delete( suspend fun TelegramBot.delete(
messages: List<AccessibleMessage> messages: List<AccessibleMessage>
) = deleteMessages(messages) ) = deleteMessages(messages)

View File

@@ -1,9 +1,12 @@
package dev.inmo.tgbotapi.extensions.api package dev.inmo.tgbotapi.extensions.api
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.send.copyMessages
import dev.inmo.tgbotapi.requests.ForwardMessages import dev.inmo.tgbotapi.requests.ForwardMessages
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import kotlin.jvm.JvmName
suspend fun TelegramBot.forwardMessages( suspend fun TelegramBot.forwardMessages(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
@@ -66,15 +69,15 @@ suspend fun TelegramBot.forwardMessages(
suspend fun TelegramBot.forwardMessages( suspend fun TelegramBot.forwardMessages(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
messages: List<AccessibleMessage>, messagesMetas: List<Message.MetaInfo>,
threadId: MessageThreadId? = toChatId.threadId, threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false, disableNotification: Boolean = false,
protectContent: Boolean = false, protectContent: Boolean = false,
removeCaption: Boolean = false removeCaption: Boolean = false
) = messages.groupBy { it.chat }.flatMap { (chat, messages) -> ) = messagesMetas.groupBy { it.chatId }.flatMap { (chatId, messages) ->
forwardMessages( forwardMessages(
toChatId = toChatId, toChatId = toChatId,
fromChatId = chat.id, fromChatId = chatId,
messageIds = messages.map { it.messageId }, messageIds = messages.map { it.messageId },
threadId = threadId, threadId = threadId,
disableNotification = disableNotification, disableNotification = disableNotification,
@@ -83,6 +86,23 @@ suspend fun TelegramBot.forwardMessages(
) )
} }
@JvmName("forwardMessagesWithMessages")
suspend fun TelegramBot.forwardMessages(
toChatId: ChatIdentifier,
messages: List<AccessibleMessage>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = forwardMessages(
toChatId = toChatId,
messagesMetas = messages.map { it.metaInfo },
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
suspend fun TelegramBot.forward( suspend fun TelegramBot.forward(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
fromChatId: ChatIdentifier, fromChatId: ChatIdentifier,
@@ -139,6 +159,23 @@ suspend fun TelegramBot.forward(
removeCaption = removeCaption removeCaption = removeCaption
) )
suspend fun TelegramBot.forward(
toChatId: ChatIdentifier,
messagesMetas: List<Message.MetaInfo>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = forwardMessages(
toChatId = toChatId,
messagesMetas = messagesMetas,
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
@JvmName("forwardWithMessages")
suspend fun TelegramBot.forward( suspend fun TelegramBot.forward(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
messages: List<AccessibleMessage>, messages: List<AccessibleMessage>,

View File

@@ -4,6 +4,8 @@ import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.send.CopyMessages import dev.inmo.tgbotapi.requests.send.CopyMessages
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import kotlin.jvm.JvmName
suspend fun TelegramBot.copyMessages( suspend fun TelegramBot.copyMessages(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
@@ -66,15 +68,15 @@ suspend fun TelegramBot.copyMessages(
suspend fun TelegramBot.copyMessages( suspend fun TelegramBot.copyMessages(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
messages: List<AccessibleMessage>, messagesMetas: List<Message.MetaInfo>,
threadId: MessageThreadId? = toChatId.threadId, threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false, disableNotification: Boolean = false,
protectContent: Boolean = false, protectContent: Boolean = false,
removeCaption: Boolean = false removeCaption: Boolean = false
) = messages.groupBy { it.chat }.flatMap { (chat, messages) -> ) = messagesMetas.groupBy { it.chatId }.flatMap { (chatId, messages) ->
copyMessages( copyMessages(
toChatId = toChatId, toChatId = toChatId,
fromChatId = chat.id, fromChatId = chatId,
messageIds = messages.map { it.messageId }, messageIds = messages.map { it.messageId },
threadId = threadId, threadId = threadId,
disableNotification = disableNotification, disableNotification = disableNotification,
@@ -82,3 +84,109 @@ suspend fun TelegramBot.copyMessages(
removeCaption = removeCaption removeCaption = removeCaption
) )
} }
@JvmName("copyMessagesWithMessages")
suspend fun TelegramBot.copyMessages(
toChatId: ChatIdentifier,
messages: List<AccessibleMessage>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = copyMessages(
toChatId = toChatId,
messagesMetas = messages.map { it.metaInfo },
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
suspend fun TelegramBot.copy(
toChatId: ChatIdentifier,
fromChatId: ChatIdentifier,
messageIds: List<MessageId>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = copyMessages(
toChatId = toChatId,
fromChatId = fromChatId,
messageIds = messageIds,
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
suspend fun TelegramBot.copy(
toChatId: ChatIdentifier,
fromChatId: ChatIdentifier,
messageIds: Array<MessageId>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = copyMessages(
toChatId = toChatId,
fromChatId = fromChatId,
messageIds = messageIds,
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
suspend fun TelegramBot.copy(
toChatId: ChatIdentifier,
fromChatId: ChatIdentifier,
firstMessageId: MessageId,
vararg messageIds: MessageId,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = copyMessages(
toChatId = toChatId,
fromChatId = fromChatId,
firstMessageId = firstMessageId,
messageIds = messageIds,
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
suspend fun TelegramBot.copy(
toChatId: ChatIdentifier,
messagesMetas: List<Message.MetaInfo>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = copyMessages(
toChatId = toChatId,
messagesMetas = messagesMetas,
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)
@JvmName("copyWithMessages")
suspend fun TelegramBot.copy(
toChatId: ChatIdentifier,
messages: List<AccessibleMessage>,
threadId: MessageThreadId? = toChatId.threadId,
disableNotification: Boolean = false,
protectContent: Boolean = false,
removeCaption: Boolean = false
) = copyMessages(
toChatId = toChatId,
messages = messages,
threadId = threadId,
disableNotification = disableNotification,
protectContent = protectContent,
removeCaption = removeCaption
)

View File

@@ -23,6 +23,7 @@ import dev.inmo.tgbotapi.types.request.UsersShared
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
typealias EventMessageToEventMapper<T> = suspend ChatEventMessage<T>.() -> T? typealias EventMessageToEventMapper<T> = suspend ChatEventMessage<T>.() -> T?
@@ -199,11 +200,16 @@ suspend fun BehaviourContext.waitChatSharedRequest(
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<ChatSharedRequest>(initRequest, errorFactory) ) = waitEvents<ChatSharedRequest>(initRequest, errorFactory)
suspend fun BehaviourContext.waitUserShared( suspend fun BehaviourContext.waitUsersShared(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<UsersShared>(initRequest, errorFactory) ) = waitEvents<UsersShared>(initRequest, errorFactory)
suspend fun BehaviourContext.waitUserShared(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitUsersShared(initRequest, errorFactory).filter { it.userIds.size == 1 }
suspend fun BehaviourContext.waitChatShared( suspend fun BehaviourContext.waitChatShared(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }

View File

@@ -23,6 +23,7 @@ import dev.inmo.tgbotapi.types.request.UsersShared
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
@RiskFeature(lowLevelRiskFeatureMessage) @RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : ChatEvent> BehaviourContext.waitEventsMessages( suspend inline fun <reified O : ChatEvent> BehaviourContext.waitEventsMessages(
@@ -193,11 +194,16 @@ suspend fun BehaviourContext.waitChatSharedRequestEventsMessages(
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ChatSharedRequest>(initRequest, errorFactory) ) = waitEventsMessages<ChatSharedRequest>(initRequest, errorFactory)
suspend fun BehaviourContext.waitUserSharedEventsMessages( suspend fun BehaviourContext.waitUsersSharedEventsMessages(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<UsersShared>(initRequest, errorFactory) ) = waitEventsMessages<UsersShared>(initRequest, errorFactory)
suspend fun BehaviourContext.waitUserSharedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitUsersSharedEventsMessages(initRequest, errorFactory).filter { it.chatEvent.userIds.size == 1 }
suspend fun BehaviourContext.waitChatSharedEventsMessages( suspend fun BehaviourContext.waitChatSharedEventsMessages(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }

View File

@@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByCha
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.chatEventMessageOrNull import dev.inmo.tgbotapi.extensions.utils.chatEventMessageOrNull
import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.*
@@ -775,7 +776,7 @@ suspend fun <BC : BehaviourContext> BC.onChatSharedRequest(
* @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
*/ */
suspend fun <BC : BehaviourContext> BC.onUserShared( suspend fun <BC : BehaviourContext> BC.onUsersShared(
initialFilter: SimpleFilter<PrivateEventMessage<UsersShared>>? = null, initialFilter: SimpleFilter<PrivateEventMessage<UsersShared>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<UsersShared>, Update>? = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<UsersShared>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<UsersShared>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<UsersShared>, Any> = ByChatMessageMarkerFactory,
@@ -783,6 +784,26 @@ suspend fun <BC : BehaviourContext> BC.onUserShared(
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEventWithCustomChatEventMessage(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.onUserShared(
initialFilter: SimpleFilter<PrivateEventMessage<UsersShared>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<UsersShared>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<UsersShared>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PrivateEventMessage<UsersShared>>
) = onUsersShared(initialFilter * { it.chatEvent.userIds.size == 1 }, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/** /**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call

View File

@@ -98,6 +98,7 @@ data class MultipartFile (
private val inputSource: () -> Input private val inputSource: () -> Input
) : InputFile() { ) : InputFile() {
@Required @Required
@EncodeDefault
override val fileId: String = "${uuid4()}.${filename.fileExtension}" override val fileId: String = "${uuid4()}.${filename.fileExtension}"
val input: Input val input: Input
get() = inputSource() get() = inputSource()

View File

@@ -112,6 +112,7 @@ data class CreateChatInviteLinkWithJoinRequest(
override val expirationUnixTimeStamp: TelegramDate? = null, override val expirationUnixTimeStamp: TelegramDate? = null,
) : CreateChatInviteLink<ChatInviteLinkWithJoinRequest>, WithJoinRequestChatInviteLinkRequest { ) : CreateChatInviteLink<ChatInviteLinkWithJoinRequest>, WithJoinRequestChatInviteLinkRequest {
@Required @Required
@EncodeDefault
@SerialName(createsJoinRequestField) @SerialName(createsJoinRequestField)
private val createsJoinRequest: Boolean = true private val createsJoinRequest: Boolean = true

View File

@@ -126,6 +126,7 @@ data class EditChatInviteLinkWithJoinRequest(
) : EditChatInviteLink<ChatInviteLinkWithJoinRequest>, ) : EditChatInviteLink<ChatInviteLinkWithJoinRequest>,
WithJoinRequestChatInviteLinkRequest { WithJoinRequestChatInviteLinkRequest {
@Required @Required
@EncodeDefault
@SerialName(createsJoinRequestField) @SerialName(createsJoinRequestField)
private val createsJoinRequest: Boolean = true private val createsJoinRequest: Boolean = true

View File

@@ -66,7 +66,7 @@ sealed interface LinkPreviewOptions {
} }
@Serializable @Serializable
data class Medium( data class Default(
@SerialName(urlField) @SerialName(urlField)
override val url: String?, override val url: String?,
@SerialName(showAboveTextField) @SerialName(showAboveTextField)
@@ -84,7 +84,7 @@ sealed interface LinkPreviewOptions {
@Serializable @Serializable
private data class Surrogate( private data class Surrogate(
@SerialName(isDisabledField) @SerialName(isDisabledField)
val isDisabled: Boolean = true, val isDisabled: Boolean = false,
@SerialName(urlField) @SerialName(urlField)
val url: String? = null, val url: String? = null,
@SerialName(preferSmallMediaField) @SerialName(preferSmallMediaField)
@@ -108,7 +108,7 @@ sealed interface LinkPreviewOptions {
surrogate.isDisabled -> Disabled surrogate.isDisabled -> Disabled
surrogate.preferLargeMedia -> Large(surrogate.url, surrogate.showAboveText) surrogate.preferLargeMedia -> Large(surrogate.url, surrogate.showAboveText)
surrogate.preferSmallMedia -> Small(surrogate.url, surrogate.showAboveText) surrogate.preferSmallMedia -> Small(surrogate.url, surrogate.showAboveText)
else -> Medium(surrogate.url, surrogate.showAboveText) else -> Default(surrogate.url, surrogate.showAboveText)
} }
} }
@@ -116,7 +116,7 @@ sealed interface LinkPreviewOptions {
when (value) { when (value) {
is Disabled -> Disabled.serializer().serialize(encoder, value) is Disabled -> Disabled.serializer().serialize(encoder, value)
is Large -> Large.serializer().serialize(encoder, value) is Large -> Large.serializer().serialize(encoder, value)
is Medium -> Medium.serializer().serialize(encoder, value) is Default -> Default.serializer().serialize(encoder, value)
is Small -> Small.serializer().serialize(encoder, value) is Small -> Small.serializer().serialize(encoder, value)
} }
} }

View File

@@ -9,13 +9,15 @@ import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.* import kotlinx.serialization.json.*
@Serializable(MenuButtonSerializer::class) @Serializable(MenuButtonSerializer::class)
@OptIn(ExperimentalSerializationApi::class)
sealed interface MenuButton { sealed interface MenuButton {
@Required @EncodeDefault
val type: String val type: String
@Serializable @Serializable
object Commands : MenuButton { object Commands : MenuButton {
@Required @Required
@EncodeDefault
override val type: String override val type: String
get() = "commands" get() = "commands"
} }
@@ -27,6 +29,7 @@ sealed interface MenuButton {
val webApp: WebAppInfo val webApp: WebAppInfo
) : MenuButton { ) : MenuButton {
@Required @Required
@EncodeDefault
override val type: String override val type: String
get() = Companion.type get() = Companion.type
@@ -39,6 +42,7 @@ sealed interface MenuButton {
@Serializable @Serializable
object Default : MenuButton { object Default : MenuButton {
@Required @Required
@EncodeDefault
override val type: String override val type: String
get() = "default" get() = "default"
} }

View File

@@ -4,10 +4,7 @@ import dev.inmo.tgbotapi.abstracts.WithMessageId
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.PreviewUser import dev.inmo.tgbotapi.types.chat.PreviewUser
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import kotlinx.serialization.KSerializer import kotlinx.serialization.*
import kotlinx.serialization.Required
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@@ -31,6 +28,7 @@ sealed interface ChatBoostSource {
override val user: PreviewUser override val user: PreviewUser
) : ByUser { ) : ByUser {
@Required @Required
@EncodeDefault
@SerialName(sourceField) @SerialName(sourceField)
override val sourceName: String = sourceCode override val sourceName: String = sourceCode
@@ -45,6 +43,7 @@ sealed interface ChatBoostSource {
override val user: PreviewUser override val user: PreviewUser
) : ByUser { ) : ByUser {
@Required @Required
@EncodeDefault
@SerialName(sourceField) @SerialName(sourceField)
override val sourceName: String = sourceCode override val sourceName: String = sourceCode
@@ -67,9 +66,11 @@ sealed interface ChatBoostSource {
override val user: PreviewUser override val user: PreviewUser
) : Giveaway, ByUser { ) : Giveaway, ByUser {
@Required @Required
@EncodeDefault
@SerialName(sourceField) @SerialName(sourceField)
override val sourceName: String = Giveaway.sourceCode override val sourceName: String = Giveaway.sourceCode
@Required @Required
@EncodeDefault
@SerialName(isUnclaimedField) @SerialName(isUnclaimedField)
override val unclaimed: Boolean = false override val unclaimed: Boolean = false
} }
@@ -80,9 +81,11 @@ sealed interface ChatBoostSource {
override val messageId: MessageId override val messageId: MessageId
) : Giveaway { ) : Giveaway {
@Required @Required
@EncodeDefault
@SerialName(sourceField) @SerialName(sourceField)
override val sourceName: String = Giveaway.sourceCode override val sourceName: String = Giveaway.sourceCode
@Required @Required
@EncodeDefault
@SerialName(isUnclaimedField) @SerialName(isUnclaimedField)
override val unclaimed: Boolean = true override val unclaimed: Boolean = true
@SerialName(userField) @SerialName(userField)
@@ -104,6 +107,7 @@ sealed interface ChatBoostSource {
@Serializable @Serializable
private data class Surrogate( private data class Surrogate(
@Required @Required
@EncodeDefault
@SerialName(sourceField) @SerialName(sourceField)
val sourceName: String, val sourceName: String,
@SerialName(userField) @SerialName(userField)

View File

@@ -65,6 +65,7 @@ data class RequestLocationKeyboardButton(
) : KeyboardButton { ) : KeyboardButton {
@SerialName(requestLocationField) @SerialName(requestLocationField)
@Required @Required
@EncodeDefault
val requestLocation: Boolean = true val requestLocation: Boolean = true
} }

View File

@@ -11,6 +11,7 @@ data class ReplyForce(
) : KeyboardMarkup { ) : KeyboardMarkup {
@SerialName(forceReplyField) @SerialName(forceReplyField)
@Required @Required
@EncodeDefault
val forceReply: Boolean = true val forceReply: Boolean = true
companion object { companion object {

View File

@@ -8,5 +8,6 @@ data class ReplyKeyboardRemove(
) : KeyboardMarkup { ) : KeyboardMarkup {
@SerialName("remove_keyboard") @SerialName("remove_keyboard")
@Required @Required
@EncodeDefault
val removeKeyboard: Boolean = true val removeKeyboard: Boolean = true
} }

View File

@@ -45,5 +45,6 @@ data class AdministratorChatMemberImpl(
) : AdministratorChatMember { ) : AdministratorChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
@EncodeDefault
override val status: ChatMember.Status = ChatMember.Status.Administrator override val status: ChatMember.Status = ChatMember.Status.Administrator
} }

View File

@@ -13,5 +13,6 @@ data class KickedChatMember(
) : BannedChatMember { ) : BannedChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
@EncodeDefault
override val status: ChatMember.Status = ChatMember.Status.Kicked override val status: ChatMember.Status = ChatMember.Status.Kicked
} }

View File

@@ -11,5 +11,6 @@ data class LeftChatMemberImpl(
) : LeftChatMember { ) : LeftChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
@EncodeDefault
override val status: ChatMember.Status = ChatMember.Status.Left override val status: ChatMember.Status = ChatMember.Status.Left
} }

View File

@@ -11,5 +11,6 @@ data class MemberChatMemberImpl(
) : MemberChatMember { ) : MemberChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
@EncodeDefault
override val status: ChatMember.Status = ChatMember.Status.Member override val status: ChatMember.Status = ChatMember.Status.Member
} }

View File

@@ -45,5 +45,6 @@ data class OwnerChatMember(
@SerialName(statusField) @SerialName(statusField)
@Required @Required
@EncodeDefault
override val status: ChatMember.Status = ChatMember.Status.Creator override val status: ChatMember.Status = ChatMember.Status.Creator
} }

View File

@@ -44,5 +44,6 @@ data class RestrictedChatMember(
) : BannedChatMember, SpecialRightsChatMember, ChatPermissions { ) : BannedChatMember, SpecialRightsChatMember, ChatPermissions {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
@EncodeDefault
override val status: ChatMember.Status = ChatMember.Status.Restricted override val status: ChatMember.Status = ChatMember.Status.Restricted
} }

View File

@@ -71,24 +71,28 @@ data class UnknownBotCommandScope internal constructor(
@Serializable @Serializable
object BotCommandScopeDefault : BotCommandScope { object BotCommandScopeDefault : BotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = "default" override val type: String = "default"
} }
@Serializable @Serializable
object BotCommandScopeAllPrivateChats : BotCommandScope { object BotCommandScopeAllPrivateChats : BotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = "all_private_chats" override val type: String = "all_private_chats"
} }
@Serializable @Serializable
object BotCommandScopeAllGroupChats : BotCommandScope { object BotCommandScopeAllGroupChats : BotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = "all_group_chats" override val type: String = "all_group_chats"
} }
@Serializable @Serializable
object BotCommandScopeAllChatAdministrators : BotCommandScope { object BotCommandScopeAllChatAdministrators : BotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = "all_chat_administrators" override val type: String = "all_chat_administrators"
} }
@@ -102,6 +106,7 @@ data class BotCommandScopeChatAdministrators(
override val chatId: ChatIdentifier override val chatId: ChatIdentifier
) : ChatBotCommandScope { ) : ChatBotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = BotCommandScopeChatAdministrators.type override val type: String = BotCommandScopeChatAdministrators.type
companion object { companion object {
const val type = "chat_administrators" const val type = "chat_administrators"
@@ -113,6 +118,7 @@ data class BotCommandScopeChat(
override val chatId: ChatIdentifier override val chatId: ChatIdentifier
) : ChatBotCommandScope { ) : ChatBotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = BotCommandScopeChat.type override val type: String = BotCommandScopeChat.type
companion object { companion object {
const val type = "chat" const val type = "chat"
@@ -125,6 +131,7 @@ data class BotCommandScopeChatMember(
val userId: UserId val userId: UserId
) : ChatBotCommandScope { ) : ChatBotCommandScope {
@Required @Required
@EncodeDefault
override val type: String = BotCommandScopeChatMember.type override val type: String = BotCommandScopeChatMember.type
companion object { companion object {
const val type = "chat_member" const val type = "chat_member"

View File

@@ -4,10 +4,7 @@ import dev.inmo.tgbotapi.abstracts.WithPreviewChatAndMessageId
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.PreviewChat import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.chat.PreviewUser import dev.inmo.tgbotapi.types.chat.PreviewUser
import kotlinx.serialization.KSerializer import kotlinx.serialization.*
import kotlinx.serialization.Required
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@@ -32,6 +29,7 @@ sealed interface GiveawayPublicResults: GiveawayInfo, GiveawayResults, WithPrevi
) : GiveawayPublicResults { ) : GiveawayPublicResults {
@SerialName(wasRefundedField) @SerialName(wasRefundedField)
@Required @Required
@EncodeDefault
override val refunded: Boolean = true override val refunded: Boolean = true
@SerialName(winnersCountField) @SerialName(winnersCountField)
override val count: Int = 0 override val count: Int = 0
@@ -78,6 +76,7 @@ sealed interface GiveawayPublicResults: GiveawayInfo, GiveawayResults, WithPrevi
) : GiveawayPublicResults { ) : GiveawayPublicResults {
@SerialName(wasRefundedField) @SerialName(wasRefundedField)
@Required @Required
@EncodeDefault
override val refunded: Boolean = false override val refunded: Boolean = false
} }

View File

@@ -2,10 +2,7 @@ package dev.inmo.tgbotapi.types.message
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.* import dev.inmo.tgbotapi.types.chat.*
import kotlinx.serialization.KSerializer import kotlinx.serialization.*
import kotlinx.serialization.Required
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@@ -27,6 +24,7 @@ sealed interface MessageOrigin {
) : MessageOrigin { ) : MessageOrigin {
@SerialName(typeField) @SerialName(typeField)
@Required @Required
@EncodeDefault
override val type: String = Companion.type override val type: String = Companion.type
companion object { companion object {
@@ -43,6 +41,7 @@ sealed interface MessageOrigin {
) : MessageOrigin { ) : MessageOrigin {
@SerialName(typeField) @SerialName(typeField)
@Required @Required
@EncodeDefault
override val type: String = Companion.type override val type: String = Companion.type
companion object { companion object {
@@ -66,6 +65,7 @@ sealed interface MessageOrigin {
) : Public { ) : Public {
@SerialName(typeField) @SerialName(typeField)
@Required @Required
@EncodeDefault
override val type: String = Companion.type override val type: String = Companion.type
companion object { companion object {
@@ -86,6 +86,7 @@ sealed interface MessageOrigin {
) : Public { ) : Public {
@SerialName(typeField) @SerialName(typeField)
@Required @Required
@EncodeDefault
override val type: String = Companion.type override val type: String = Companion.type
companion object { companion object {
@@ -105,6 +106,7 @@ sealed interface MessageOrigin {
private data class Surrogate( private data class Surrogate(
@SerialName(typeField) @SerialName(typeField)
@Required @Required
@EncodeDefault
val type: String, val type: String,
@SerialName(senderChatField) @SerialName(senderChatField)
val senderChat: PreviewChat? = null, val senderChat: PreviewChat? = null,

View File

@@ -100,6 +100,7 @@ data class PassportElementErrorDataField(
) : PassportSingleElementError() { ) : PassportSingleElementError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = dataField override val source: String = dataField
} }
fun EncryptedPassportElementWithData.createDataError(field: String, message: String) = PassportElementErrorDataField( fun EncryptedPassportElementWithData.createDataError(field: String, message: String) = PassportElementErrorDataField(
@@ -121,6 +122,7 @@ data class PassportElementErrorFrontSide(
) : PassportElementFileError() { ) : PassportElementFileError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = frontSideField override val source: String = frontSideField
} }
fun EncryptedPassportElementWithFrontSide.createFrontSideError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorFrontSide( fun EncryptedPassportElementWithFrontSide.createFrontSideError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorFrontSide(
@@ -141,6 +143,7 @@ data class PassportElementErrorReverseSide(
) : PassportElementFileError() { ) : PassportElementFileError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = reverseSideField override val source: String = reverseSideField
} }
fun EncryptedPassportElementWithReverseSide.createReverseSideError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorReverseSide( fun EncryptedPassportElementWithReverseSide.createReverseSideError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorReverseSide(
@@ -160,6 +163,7 @@ data class PassportElementErrorSelfie(
) : PassportElementFileError() { ) : PassportElementFileError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = selfieField override val source: String = selfieField
} }
fun EncryptedPassportElementWithSelfie.createSelfieError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorSelfie( fun EncryptedPassportElementWithSelfie.createSelfieError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorSelfie(
@@ -181,6 +185,7 @@ data class PassportElementErrorFile(
) : PassportElementFileError() { ) : PassportElementFileError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = fileField override val source: String = fileField
} }
fun EncryptedPassportElementWithFilesCollection.createFileError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorFile( fun EncryptedPassportElementWithFilesCollection.createFileError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorFile(
@@ -200,6 +205,7 @@ data class PassportElementErrorFiles(
) : PassportElementFilesError() { ) : PassportElementFilesError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = filesField override val source: String = filesField
} }
fun EncryptedPassportElementWithFilesCollection.createFilesError(message: String, unencryptedFileHashes: List<PassportElementHash>) = PassportElementErrorFiles( fun EncryptedPassportElementWithFilesCollection.createFilesError(message: String, unencryptedFileHashes: List<PassportElementHash>) = PassportElementErrorFiles(
@@ -221,6 +227,7 @@ data class PassportElementErrorTranslationFile(
) : PassportElementFileError() { ) : PassportElementFileError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = translationFileField override val source: String = translationFileField
} }
fun EncryptedPassportElementTranslatable.createFileError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorTranslationFile( fun EncryptedPassportElementTranslatable.createFileError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorTranslationFile(
@@ -239,6 +246,7 @@ data class PassportElementErrorTranslationFiles(
) : PassportElementFilesError() { ) : PassportElementFilesError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = translationFilesField override val source: String = translationFilesField
} }
fun EncryptedPassportElementTranslatable.createFilesError(message: String, unencryptedFileHashes: List<PassportElementHash>) = PassportElementErrorTranslationFiles( fun EncryptedPassportElementTranslatable.createFilesError(message: String, unencryptedFileHashes: List<PassportElementHash>) = PassportElementErrorTranslationFiles(
@@ -259,6 +267,7 @@ data class PassportElementErrorUnspecified(
) : PassportElementFileError() { ) : PassportElementFileError() {
@SerialName(sourceField) @SerialName(sourceField)
@Required @Required
@EncodeDefault
override val source: String = unspecifiedField override val source: String = unspecifiedField
} }
fun EncryptedPassportElement.createUnspecifiedError(message: String, elementHash: PassportElementHash) = PassportElementErrorUnspecified( fun EncryptedPassportElement.createUnspecifiedError(message: String, elementHash: PassportElementHash) = PassportElementErrorUnspecified(

View File

@@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.types.buttons.*
import dev.inmo.tgbotapi.types.buttons.reply.requestChatReplyButton import dev.inmo.tgbotapi.types.buttons.reply.requestChatReplyButton
import dev.inmo.tgbotapi.types.buttons.reply.requestUserReplyButton import dev.inmo.tgbotapi.types.buttons.reply.requestUserReplyButton
import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights
import dev.inmo.tgbotapi.types.keyboardButtonRequestUserLimit
import dev.inmo.tgbotapi.types.request.RequestId import dev.inmo.tgbotapi.types.request.RequestId
import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import dev.inmo.tgbotapi.utils.* import dev.inmo.tgbotapi.utils.*
@@ -137,7 +138,7 @@ inline fun ReplyKeyboardRowBuilder.webAppButton(
* @see replyKeyboard * @see replyKeyboard
* @see ReplyKeyboardBuilder.row * @see ReplyKeyboardBuilder.row
*/ */
inline fun ReplyKeyboardRowBuilder.requestUserButton( inline fun ReplyKeyboardRowBuilder.requestUsersButton(
text: String, text: String,
requestUser: KeyboardButtonRequestUsers requestUser: KeyboardButtonRequestUsers
) = add( ) = add(
@@ -147,6 +148,33 @@ inline fun ReplyKeyboardRowBuilder.requestUserButton(
) )
) )
/**
* Creates and put [RequestUserKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
@Deprecated("Renamed", ReplaceWith("requestUsersButton(text, requestUser)", "dev.inmo.tgbotapi.extensions.utils.types.buttons"))
inline fun ReplyKeyboardRowBuilder.requestUserButton(
text: String,
requestUser: KeyboardButtonRequestUsers
) = requestUsersButton(text, requestUser)
/**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUsers.Bot]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestBotsButton(
text: String,
requestId: RequestId,
maxCount: Int
) = requestUsersButton(
text,
KeyboardButtonRequestUsers.Bot(requestId, maxCount)
)
/** /**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUsers.Bot] * Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUsers.Bot]
* *
@@ -156,9 +184,26 @@ inline fun ReplyKeyboardRowBuilder.requestUserButton(
inline fun ReplyKeyboardRowBuilder.requestBotButton( inline fun ReplyKeyboardRowBuilder.requestBotButton(
text: String, text: String,
requestId: RequestId requestId: RequestId
) = requestUserButton( ) = requestBotsButton(
text, text,
KeyboardButtonRequestUsers.Bot(requestId) requestId,
maxCount = keyboardButtonRequestUserLimit.first
)
/**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUsers.Common]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUsersButton(
text: String,
requestId: RequestId,
premiumUser: Boolean? = null,
maxCount: Int
) = requestUsersButton(
text,
KeyboardButtonRequestUsers.Common(requestId, premiumUser, maxCount)
) )
/** /**
@@ -171,9 +216,21 @@ inline fun ReplyKeyboardRowBuilder.requestUserButton(
text: String, text: String,
requestId: RequestId, requestId: RequestId,
premiumUser: Boolean? = null premiumUser: Boolean? = null
) = requestUserButton( ) = requestUsersButton(text, requestId, premiumUser, maxCount = keyboardButtonRequestUserLimit.first)
/**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUsers.Any]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUsersOrBotsButton(
text: String,
requestId: RequestId,
maxCount: Int
) = requestUsersButton(
text, text,
KeyboardButtonRequestUsers.Common(requestId, premiumUser) KeyboardButtonRequestUsers.Any(requestId, maxCount)
) )
/** /**
@@ -185,9 +242,10 @@ inline fun ReplyKeyboardRowBuilder.requestUserButton(
inline fun ReplyKeyboardRowBuilder.requestUserOrBotButton( inline fun ReplyKeyboardRowBuilder.requestUserOrBotButton(
text: String, text: String,
requestId: RequestId requestId: RequestId
) = requestUserButton( ) = requestUsersOrBotsButton(
text, text,
KeyboardButtonRequestUsers.Any(requestId) requestId,
maxCount = keyboardButtonRequestUserLimit.first
) )