some progress on business chats

This commit is contained in:
InsanusMokrassar 2024-04-16 19:25:18 +06:00
parent 8de584b292
commit c1f40c1030
8 changed files with 91 additions and 14 deletions

View File

@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.requests.chat.get
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.BusinessChatId
import dev.inmo.tgbotapi.types.ChatIdWithThreadId
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.chat.ExtendedChatSerializer
@ -16,10 +17,10 @@ data class GetChat(
): ChatRequest, SimpleRequest<ExtendedChat> {
override fun method(): String = "getChat"
@Transient
override val resultDeserializer: DeserializationStrategy<ExtendedChat> = if (chatId is ChatIdWithThreadId) {
ExtendedChatSerializer.BasedOnForumThread(chatId.threadId)
} else {
ExtendedChatSerializer.Companion
override val resultDeserializer: DeserializationStrategy<ExtendedChat> = when {
chatId is ChatIdWithThreadId -> ExtendedChatSerializer.BasedOnForumThread(chatId.threadId)
chatId is BusinessChatId -> ExtendedChatSerializer.BasedOnBusinessConnection(chatId.businessId)
else -> ExtendedChatSerializer.Companion
}
override val requestSerializer: SerializationStrategy<*>
get() = serializer()

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
@ -29,12 +30,17 @@ sealed interface IdChatIdentifier : ChatIdentifier {
abstract val chatId: RawChatId
val threadId: MessageThreadId?
get() = null
val businessId: BusinessConnectionId?
get() = null
companion object {
operator fun invoke(chatId: RawChatId) = ChatId(chatId)
operator fun invoke(chatId: RawChatId, threadId: MessageThreadId?) = threadId ?.let {
ChatIdWithThreadId(chatId, threadId)
} ?: ChatId(chatId)
operator fun invoke(chatId: RawChatId, businessConnectionId: BusinessConnectionId?) = businessConnectionId ?.let {
BusinessChatId(chatId, businessConnectionId)
} ?: ChatId(chatId)
}
}
@ -52,6 +58,16 @@ value class ChatIdWithThreadId(val chatIdWithThreadId: Pair<RawChatId, MessageTh
constructor(chatId: RawChatId, threadId: MessageThreadId): this(chatId to threadId)
}
@Serializable(ChatIdentifierSerializer::class)
@JvmInline
value class BusinessChatId(val chatIdWithBusinessConnectionId: Pair<RawChatId, BusinessConnectionId>) : IdChatIdentifier {
override val chatId: RawChatId
get() = chatIdWithBusinessConnectionId.first
override val businessId: BusinessConnectionId
get() = chatIdWithBusinessConnectionId.second
constructor(chatId: RawChatId, businessConnectionId: BusinessConnectionId): this(chatId to businessConnectionId)
}
val ChatIdentifier.threadId: MessageThreadId?
get() = (this as? IdChatIdentifier) ?.threadId
@ -59,9 +75,11 @@ val ChatIdentifier.threadId: MessageThreadId?
fun IdChatIdentifier.toChatId() = when (this) {
is ChatId -> this
is ChatIdWithThreadId -> ChatId(chatId)
is BusinessChatId -> ChatId(chatId)
}
fun IdChatIdentifier.toChatWithThreadId(threadId: MessageThreadId) = IdChatIdentifier(chatId, threadId)
fun IdChatIdentifier.toBusinessChatId(businessConnectionId: BusinessConnectionId) = IdChatIdentifier(chatId, businessConnectionId)
/**
* https://core.telegram.org/bots/api#formatting-options
@ -145,14 +163,22 @@ object FullChatIdentifierSerializer : KSerializer<ChatIdentifier> {
ChatId(RawChatId(it))
} ?:let {
val splitted = id.content.split("/")
if (splitted.size == 2) {
val (chatId, threadId) = splitted
ChatIdWithThreadId(
chatId.toLongOrNull() ?.let(::RawChatId) ?: return@let null,
threadId.toLongOrNull() ?.let(::MessageThreadId) ?: return@let null
)
} else {
null
when (splitted.size) {
2 -> {
val (chatId, threadId) = splitted
ChatIdWithThreadId(
chatId.toLongOrNull() ?.let(::RawChatId) ?: return@let null,
threadId.toLongOrNull() ?.let(::MessageThreadId) ?: return@let null
)
}
3 -> {
val (chatId, _, businessConnectionId) = splitted
BusinessChatId(
chatId.toLongOrNull() ?.let(::RawChatId) ?: return@let null,
businessConnectionId.let(::BusinessConnectionId) ?: return@let null
)
}
else -> null
}
} ?: id.content.let {
if (!it.startsWith("@")) {
@ -167,6 +193,7 @@ object FullChatIdentifierSerializer : KSerializer<ChatIdentifier> {
when (value) {
is ChatId -> encoder.encodeLong(value.chatId.long)
is ChatIdWithThreadId -> encoder.encodeString("${value.chatId}/${value.threadId}")
is BusinessChatId -> encoder.encodeString("${value.chatId}//${value.businessId}")
is Username -> encoder.encodeString(value.full)
}
}

View File

@ -7,4 +7,8 @@ import kotlin.jvm.JvmInline
@JvmInline
value class BusinessConnectionId(
val string: String
)
) {
override fun toString(): String {
return string
}
}

View File

@ -16,6 +16,12 @@ sealed interface PrivateChat : Chat, UsernameChat {
val lastName: String
}
@Serializable(ChatSerializer::class)
sealed interface BusinessChat : Chat {
override val id: BusinessChatId
val original: PrivateChat
}
@Serializable(ChatSerializer::class)
sealed interface PublicChat : Chat {
val title: String

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.*
@ -103,10 +104,17 @@ object PreviewChatSerializer : KSerializer<PreviewChat> {
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
val isForum = decodedJson[isForumField] ?.jsonPrimitive ?.booleanOrNull == true
val isBusiness = decodedJson[chatIdField] ?.jsonPrimitive ?.contentOrNull ?.contains("//") == true
return when (type) {
ChatType.Sender -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson)
ChatType.Private -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson)
ChatType.Private -> {
if (isBusiness) {
formatter.decodeFromJsonElement(BusinessChatImpl.serializer(), decodedJson)
} else {
formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson)
}
}
ChatType.Group -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson)
ChatType.Supergroup -> if (isForum) {
formatter.decodeFromJsonElement(ForumChatImpl.serializer(), decodedJson)
@ -125,6 +133,7 @@ object PreviewChatSerializer : KSerializer<PreviewChat> {
override fun serialize(encoder: Encoder, value: PreviewChat) {
when (value) {
is PrivateChatImpl -> PrivateChatImpl.serializer().serialize(encoder, value)
is BusinessChatImpl -> BusinessChatImpl.serializer().serialize(encoder, value)
is GroupChatImpl -> GroupChatImpl.serializer().serialize(encoder, value)
is SupergroupChatImpl -> SupergroupChatImpl.serializer().serialize(encoder, value)
is ForumChatImpl -> ForumChatImpl.serializer().serialize(encoder, value)
@ -190,6 +199,19 @@ sealed class ExtendedChatSerializer : KSerializer<ExtendedChat> {
}
}
}
class BasedOnBusinessConnection(private val businessConnectionId: BusinessConnectionId) : ExtendedChatSerializer() {
override fun deserialize(decoder: Decoder): ExtendedChat {
return super.deserialize(decoder).let {
if (it is ExtendedPrivateChatImpl) {
it.copy(
id = (it.id as? BusinessChatId) ?: BusinessChatId(it.id.chatId, businessConnectionId)
)
} else {
it
}
}
}
}
companion object : ExtendedChatSerializer()
}

View File

@ -93,3 +93,8 @@ sealed interface ExtendedForumChat : ExtendedSupergroupChat, ForumChat
sealed interface ExtendedChatWithUsername : UsernameChat, ExtendedChat {
val activeUsernames: List<Username>
}
@Serializable(ExtendedChatSerializer.Companion::class)
sealed interface ExtendedBusinessChat : BusinessChat, ExtendedChat {
override val original: ExtendedPrivateChat
}

View File

@ -30,6 +30,15 @@ data class PrivateChatImpl(
override val lastName: String = ""
) : PreviewPrivateChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use PrivateChat due")
data class BusinessChatImpl(
@SerialName(idField)
override val id: BusinessChatId,
@SerialName(firstNameField)
override val original: PreviewPrivateChat
) : PreviewBusinessChat
@Serializable
@RiskFeature("This class is a subject of changes. It is better to use SupergroupChat due")
data class SupergroupChatImpl(

View File

@ -11,6 +11,9 @@ sealed interface PreviewUsernameChat : PreviewChat, UsernameChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewPrivateChat : PreviewUsernameChat, PrivateChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewBusinessChat : BusinessChat, PreviewChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewPublicChat : PreviewChat, PublicChat