diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt index 51a3dd4859..1aec90b33c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt @@ -319,6 +319,7 @@ const val scaleField = "scale" const val maxTipAmountField = "max_tip_amount" const val suggestedTipAmountsField = "suggested_tip_amounts" +const val chatTypeField = "chat_type" const val explanationEntitiesField = "explanation_entities" const val explanationParseModeField = "explanation_parse_mode" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/abstracts/InlineQuery.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/abstracts/InlineQuery.kt index c785cf5801..d942a452d7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/abstracts/InlineQuery.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/abstracts/InlineQuery.kt @@ -2,10 +2,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.abstracts import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.User +import dev.inmo.tgbotapi.types.chat.ChatType interface InlineQuery { val id: InlineQueryIdentifier val from: User val query: String val offset: String + val chatType: ChatType? } \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/BaseInlineQuery.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/BaseInlineQuery.kt index ba1e09280a..c127b2f1c1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/BaseInlineQuery.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/BaseInlineQuery.kt @@ -3,10 +3,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.query import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.User +import dev.inmo.tgbotapi.types.chat.ChatType data class BaseInlineQuery( override val id: InlineQueryIdentifier, override val from: User, override val query: String, - override val offset: String + override val offset: String, + override val chatType: ChatType? ) : InlineQuery diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/LocationInlineQuery.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/LocationInlineQuery.kt index fe94c7e34d..89ce364dbf 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/LocationInlineQuery.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/LocationInlineQuery.kt @@ -3,12 +3,15 @@ package dev.inmo.tgbotapi.types.InlineQueries.query import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.User +import dev.inmo.tgbotapi.types.chat.ChatType import dev.inmo.tgbotapi.types.location.Location +import kotlinx.serialization.Serializable data class LocationInlineQuery( override val id: InlineQueryIdentifier, override val from: User, override val query: String, override val offset: String, + override val chatType: ChatType?, val location: Location ) : InlineQuery diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/RawInlineQuery.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/RawInlineQuery.kt index eaf43fca71..e660c71882 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/RawInlineQuery.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/query/RawInlineQuery.kt @@ -1,9 +1,10 @@ package dev.inmo.tgbotapi.types.InlineQueries.query import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.chat.ChatType +import dev.inmo.tgbotapi.types.chat.ChatTypeSerializer import dev.inmo.tgbotapi.types.location.Location -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import kotlinx.serialization.* @Serializable internal data class RawInlineQuery( @@ -15,12 +16,15 @@ internal data class RawInlineQuery( val query: String, @SerialName(offsetField) val offset: String, + @SerialName(chatTypeField) + @Serializable(ChatTypeSerializer::class) + val chatType: ChatType? = null, @SerialName(locationField) val location: Location? = null ) { val asInlineQuery by lazy { location ?.let { - LocationInlineQuery(id, from, query, offset, location) - } ?: BaseInlineQuery(id, from, query, offset) + LocationInlineQuery(id, from, query, offset, chatType, location) + } ?: BaseInlineQuery(id, from, query, offset, chatType) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatSerializers.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatSerializers.kt index 23a27339a0..56a0c78fb1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatSerializers.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatSerializers.kt @@ -4,10 +4,10 @@ import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.chat.abstracts.UnknownChatType import dev.inmo.tgbotapi.types.chat.abstracts.extended.ExtendedChat +import dev.inmo.tgbotapi.types.chat.abstracts.extended.UnknownExtendedChat import dev.inmo.tgbotapi.types.chat.extended.* import dev.inmo.tgbotapi.utils.nonstrictJsonFormat -import kotlinx.serialization.InternalSerializationApi -import kotlinx.serialization.KSerializer +import kotlinx.serialization.* import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.Decoder @@ -17,6 +17,40 @@ import kotlinx.serialization.json.* private val formatter get() = nonstrictJsonFormat +@Serializable(ChatTypeSerializer::class) +sealed class ChatType { + abstract val stringified: String + @Serializable(ChatTypeSerializer::class) + object PrivateChatType : ChatType() { override val stringified = "private" } + @Serializable(ChatTypeSerializer::class) + object GroupChatType : ChatType() { override val stringified = "group" } + @Serializable(ChatTypeSerializer::class) + object SupergroupChatType : ChatType() { override val stringified = "supergroup" } + @Serializable(ChatTypeSerializer::class) + object ChannelChatType : ChatType() { override val stringified = "channel" } + @Serializable(ChatTypeSerializer::class) + class UnknownChatType(override val stringified: String) : ChatType() +} +val String.asChatType + get() = when (this) { + ChatType.PrivateChatType.stringified -> ChatType.PrivateChatType + ChatType.GroupChatType.stringified -> ChatType.GroupChatType + ChatType.SupergroupChatType.stringified -> ChatType.SupergroupChatType + ChatType.ChannelChatType.stringified -> ChatType.ChannelChatType + else -> ChatType.UnknownChatType(this) + } +@Serializer(ChatType::class) +object ChatTypeSerializer : KSerializer { + override val descriptor: SerialDescriptor = String.serializer().descriptor + override fun deserialize(decoder: Decoder): ChatType { + return decoder.decodeString().asChatType + } + + override fun serialize(encoder: Encoder, value: ChatType) { + encoder.encodeString(value.stringified) + } +} + internal object PreviewChatSerializer : KSerializer { @InternalSerializationApi override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN) @@ -24,14 +58,14 @@ internal object PreviewChatSerializer : KSerializer { override fun deserialize(decoder: Decoder): Chat { val decodedJson = JsonObject.serializer().deserialize(decoder) - val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?: error("Field $typeField must be presented, but absent in $decodedJson") + val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson") return when (type) { - "private" -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson) - "group" -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson) - "supergroup" -> formatter.decodeFromJsonElement(SupergroupChatImpl.serializer(), decodedJson) - "channel" -> formatter.decodeFromJsonElement(ChannelChatImpl.serializer(), decodedJson) - else -> UnknownChatType( + ChatType.PrivateChatType -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson) + ChatType.GroupChatType -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson) + ChatType.SupergroupChatType -> formatter.decodeFromJsonElement(SupergroupChatImpl.serializer(), decodedJson) + ChatType.ChannelChatType -> formatter.decodeFromJsonElement(ChannelChatImpl.serializer(), decodedJson) + is ChatType.UnknownChatType -> UnknownChatType( formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(), decodedJson.toString() ) @@ -56,14 +90,18 @@ internal object ExtendedChatSerializer : KSerializer { override fun deserialize(decoder: Decoder): ExtendedChat { val decodedJson = JsonObject.serializer().deserialize(decoder) - val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?: error("Field $typeField must be presented, but absent in $decodedJson") + val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson") return when (type) { - "private" -> formatter.decodeFromJsonElement(ExtendedPrivateChatImpl.serializer(), decodedJson) - "group" -> formatter.decodeFromJsonElement(ExtendedGroupChatImpl.serializer(), decodedJson) - "supergroup" -> formatter.decodeFromJsonElement(ExtendedSupergroupChatImpl.serializer(), decodedJson) - "channel" -> formatter.decodeFromJsonElement(ExtendedChannelChatImpl.serializer(), decodedJson) - else -> throw IllegalArgumentException("Unknown type of chat") +// else -> throw IllegalArgumentException("Unknown type of chat") + ChatType.PrivateChatType -> formatter.decodeFromJsonElement(ExtendedPrivateChatImpl.serializer(), decodedJson) + ChatType.GroupChatType -> formatter.decodeFromJsonElement(ExtendedGroupChatImpl.serializer(), decodedJson) + ChatType.SupergroupChatType -> formatter.decodeFromJsonElement(ExtendedSupergroupChatImpl.serializer(), decodedJson) + ChatType.ChannelChatType -> formatter.decodeFromJsonElement(ExtendedChannelChatImpl.serializer(), decodedJson) + is ChatType.UnknownChatType -> UnknownExtendedChat( + formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(), + decodedJson.toString() + ) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/abstracts/extended/ExtendedChat.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/abstracts/extended/ExtendedChat.kt index 9a888d273c..dea56901e6 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/abstracts/extended/ExtendedChat.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/abstracts/extended/ExtendedChat.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.types.chat.abstracts.extended +import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatPhoto import dev.inmo.tgbotapi.types.chat.ExtendedChatSerializer import dev.inmo.tgbotapi.types.chat.abstracts.Chat @@ -8,4 +9,11 @@ import kotlinx.serialization.Serializable @Serializable(ExtendedChatSerializer::class) interface ExtendedChat : Chat { val chatPhoto: ChatPhoto? -} \ No newline at end of file +} + +data class UnknownExtendedChat( + override val id: ChatId, + val raw: String +) : ExtendedChat { + override val chatPhoto: ChatPhoto? = null +}