1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-06-14 05:45:26 +00:00
tgbotapi/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatIdentifier.kt

204 lines
7.2 KiB
Kotlin
Raw Normal View History

2020-10-04 11:06:30 +00:00
package dev.inmo.tgbotapi.types
2018-12-26 08:07:24 +00:00
2021-02-09 11:15:28 +00:00
import dev.inmo.micro_utils.common.Warning
2024-04-16 13:25:18 +00:00
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
2022-04-21 18:16:41 +00:00
import dev.inmo.tgbotapi.types.chat.User
2021-05-29 09:34:14 +00:00
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
2021-06-28 05:12:51 +00:00
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
2021-05-29 09:34:14 +00:00
import kotlinx.serialization.descriptors.SerialDescriptor
2020-08-18 06:50:11 +00:00
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
2020-11-05 18:12:14 +00:00
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.longOrNull
2022-11-10 09:56:38 +00:00
import kotlin.jvm.JvmInline
2018-12-26 08:07:24 +00:00
const val internalTgAppLinksBeginning = "tg://"
2022-07-09 16:43:19 +00:00
const val internalLinkBeginning = "https://t.me"
const val internalUserLinkBeginning = "${internalTgAppLinksBeginning}user?id="
2022-07-09 16:43:19 +00:00
2018-12-26 08:07:24 +00:00
@Serializable(ChatIdentifierSerializer::class)
@ClassCastsIncluded
2022-11-10 09:56:38 +00:00
sealed interface ChatIdentifier
2018-12-26 08:07:24 +00:00
/**
* Also used as User Identifier
*/
@Serializable(ChatIdentifierSerializer::class)
2022-11-10 09:56:38 +00:00
sealed interface IdChatIdentifier : ChatIdentifier {
2024-03-16 16:40:42 +00:00
abstract val chatId: RawChatId
2022-11-10 09:56:38 +00:00
val threadId: MessageThreadId?
get() = null
2024-04-16 13:25:18 +00:00
val businessId: BusinessConnectionId?
get() = null
2022-11-10 09:56:38 +00:00
companion object {
operator fun invoke(chatId: RawChatId, threadId: MessageThreadId? = null, businessConnectionId: BusinessConnectionId? = null) = threadId ?.let {
ChatIdWithThreadId(chatId, threadId)
} ?: businessConnectionId ?.let {
2024-04-16 13:25:18 +00:00
BusinessChatId(chatId, businessConnectionId)
} ?: ChatId(chatId)
operator fun invoke(chatId: RawChatId, threadId: MessageThreadId) = ChatIdWithThreadId(chatId, threadId)
operator fun invoke(chatId: RawChatId, businessConnectionId: BusinessConnectionId) = BusinessChatId(chatId, businessConnectionId)
2022-11-10 09:56:38 +00:00
}
}
@Serializable(ChatIdentifierSerializer::class)
@JvmInline
2024-03-16 16:40:42 +00:00
value class ChatId(override val chatId: RawChatId) : IdChatIdentifier
2022-11-10 09:56:38 +00:00
@Serializable(ChatIdentifierSerializer::class)
@JvmInline
2024-03-16 16:40:42 +00:00
value class ChatIdWithThreadId(val chatIdWithThreadId: Pair<RawChatId, MessageThreadId>) : IdChatIdentifier {
override val chatId: RawChatId
2022-11-10 09:56:38 +00:00
get() = chatIdWithThreadId.first
override val threadId: MessageThreadId
get() = chatIdWithThreadId.second
2024-03-16 16:40:42 +00:00
constructor(chatId: RawChatId, threadId: MessageThreadId): this(chatId to threadId)
2022-11-10 09:56:38 +00:00
}
2024-04-16 13:25:18 +00:00
@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)
}
2022-11-10 09:56:38 +00:00
val ChatIdentifier.threadId: MessageThreadId?
get() = (this as? IdChatIdentifier) ?.threadId
2018-12-26 08:07:24 +00:00
val ChatIdentifier.businessConnectionId: BusinessConnectionId?
get() = (this as? IdChatIdentifier) ?.businessConnectionId
2022-12-13 04:52:56 +00:00
fun IdChatIdentifier.toChatId() = when (this) {
is ChatId -> this
is ChatIdWithThreadId -> ChatId(chatId)
2024-04-16 13:25:18 +00:00
is BusinessChatId -> ChatId(chatId)
2022-12-13 04:52:56 +00:00
}
fun IdChatIdentifier.toChatWithThreadId(threadId: MessageThreadId) = IdChatIdentifier(chatId, threadId)
2024-04-16 13:25:18 +00:00
fun IdChatIdentifier.toBusinessChatId(businessConnectionId: BusinessConnectionId) = IdChatIdentifier(chatId, businessConnectionId)
2022-12-13 04:52:56 +00:00
2021-02-09 11:15:28 +00:00
/**
* https://core.telegram.org/bots/api#formatting-options
*/
@Warning("This API have restrictions in Telegram System")
2024-03-16 16:40:42 +00:00
val RawChatId.userLink: String
2023-02-13 05:16:49 +00:00
get() = "$internalUserLinkBeginning$this"
2021-02-09 11:15:28 +00:00
/**
* https://core.telegram.org/bots/api#formatting-options
*/
@Warning("This API have restrictions in Telegram System")
2022-07-09 16:43:19 +00:00
val UserId.userLink: String
get() = chatId.userLink
2023-02-27 16:32:08 +00:00
val User.userLink: String
2022-07-09 16:43:19 +00:00
get() = id.userLink
2022-11-20 07:21:20 +00:00
typealias UserId = ChatId
2018-12-26 08:07:24 +00:00
2024-03-16 16:40:42 +00:00
fun RawChatId.toChatId(): ChatId = ChatId(this)
fun Long.toChatId(): ChatId = ChatId(RawChatId(this))
fun Int.toChatId(): IdChatIdentifier = RawChatId(toLong()).toChatId()
fun Byte.toChatId(): IdChatIdentifier = RawChatId(toLong()).toChatId()
2018-12-26 08:07:24 +00:00
@Serializable(ChatIdentifierSerializer::class)
2024-01-07 14:05:05 +00:00
@JvmInline
value class Username(
val full: String
2024-03-16 13:29:10 +00:00
) : ChatIdentifier {
val username: String
get() = full
2024-01-07 15:56:31 +00:00
val withoutAt
get() = full.dropWhile { it == '@' }
2022-02-07 12:08:06 +00:00
2019-02-18 06:35:58 +00:00
init {
2024-01-09 05:45:12 +00:00
if (!full.startsWith("@")) {
2019-02-18 06:35:58 +00:00
throw IllegalArgumentException("Username must starts with `@`")
2019-02-18 04:53:01 +00:00
}
2018-12-26 08:07:24 +00:00
}
2024-01-07 14:05:05 +00:00
override fun toString(): String {
return full
}
2018-12-26 08:07:24 +00:00
}
2019-06-02 14:57:52 +00:00
fun String.toUsername(): Username = Username(this)
2018-12-26 08:07:24 +00:00
2021-05-29 09:34:14 +00:00
@RiskFeature
object ChatIdentifierSerializer : KSerializer<ChatIdentifier> {
private val internalSerializer = JsonPrimitive.serializer()
override val descriptor: SerialDescriptor = internalSerializer.descriptor
2019-02-21 06:21:33 +00:00
override fun deserialize(decoder: Decoder): ChatIdentifier {
2021-05-29 09:34:14 +00:00
val id = internalSerializer.deserialize(decoder)
2022-11-11 15:44:37 +00:00
2020-03-22 09:53:37 +00:00
return id.longOrNull ?.let {
2024-03-16 16:40:42 +00:00
ChatId(RawChatId(it))
2020-03-22 09:53:37 +00:00
} ?: id.content.let {
if (!it.startsWith("@")) {
Username("@$it")
} else {
Username(it)
}
2019-02-18 06:35:58 +00:00
}
2018-12-26 08:07:24 +00:00
}
2020-03-22 07:37:01 +00:00
override fun serialize(encoder: Encoder, value: ChatIdentifier) {
when (value) {
2024-03-16 16:40:42 +00:00
is IdChatIdentifier -> encoder.encodeLong(value.chatId.long)
2024-01-09 05:45:12 +00:00
is Username -> encoder.encodeString(value.full)
2018-12-26 08:07:24 +00:00
}
}
2021-05-29 09:34:14 +00:00
}
2022-11-11 15:44:37 +00:00
@RiskFeature
object FullChatIdentifierSerializer : KSerializer<ChatIdentifier> {
private val internalSerializer = JsonPrimitive.serializer()
override val descriptor: SerialDescriptor = internalSerializer.descriptor
override fun deserialize(decoder: Decoder): ChatIdentifier {
val id = internalSerializer.deserialize(decoder)
return id.longOrNull ?.let {
2024-03-16 16:40:42 +00:00
ChatId(RawChatId(it))
2022-11-11 15:44:37 +00:00
} ?:let {
val splitted = id.content.split("/")
2024-04-16 13:25:18 +00:00
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
2022-11-11 15:44:37 +00:00
}
} ?: id.content.let {
if (!it.startsWith("@")) {
Username("@$it")
} else {
Username(it)
}
}
}
override fun serialize(encoder: Encoder, value: ChatIdentifier) {
when (value) {
2024-03-16 16:40:42 +00:00
is ChatId -> encoder.encodeLong(value.chatId.long)
2022-11-11 15:44:37 +00:00
is ChatIdWithThreadId -> encoder.encodeString("${value.chatId}/${value.threadId}")
2024-04-16 13:25:18 +00:00
is BusinessChatId -> encoder.encodeString("${value.chatId}//${value.businessId}")
2024-01-09 05:45:12 +00:00
is Username -> encoder.encodeString(value.full)
2022-11-11 15:44:37 +00:00
}
}
}