1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-12-22 00:27:14 +00:00

add support for gifts

This commit is contained in:
InsanusMokrassar 2024-12-05 09:09:40 +06:00
parent bc00e1f28a
commit 4ac5e405ac
8 changed files with 301 additions and 1 deletions

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.extensions.api.gifts
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.gifts.GetAvailableGifts
import dev.inmo.tgbotapi.types.gifts.Gifts
public suspend fun TelegramBot.getAvailableGifts(): Gifts = execute(GetAvailableGifts)

View File

@ -0,0 +1,103 @@
package dev.inmo.tgbotapi.extensions.api.gifts
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.gifts.SendGift
import dev.inmo.tgbotapi.types.GiftId
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.gifts.Gift
import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
public suspend fun TelegramBot.sendGift(
userId: UserId,
giftId: GiftId,
text: String,
parseMode: ParseMode?
): Boolean = execute(
SendGift(
userId,
giftId,
text,
parseMode
)
)
public suspend fun TelegramBot.sendGift(
userId: UserId,
giftId: GiftId,
textSources: TextSourcesList,
): Boolean = execute(
SendGift(
userId,
giftId,
textSources
)
)
public suspend fun TelegramBot.sendGift(
user: User,
giftId: GiftId,
text: String,
parseMode: ParseMode?
): Boolean = sendGift(
user.id,
giftId,
text,
parseMode
)
public suspend fun TelegramBot.sendGift(
user: User,
giftId: GiftId,
textSources: TextSourcesList,
): Boolean = sendGift(
user.id,
giftId,
textSources
)
public suspend fun TelegramBot.sendGift(
user: UserId,
gift: Gift,
text: String,
parseMode: ParseMode?
): Boolean = sendGift(
user,
gift.id,
text,
parseMode
)
public suspend fun TelegramBot.sendGift(
user: UserId,
gift: Gift,
textSources: TextSourcesList,
): Boolean = sendGift(
user,
gift.id,
textSources
)
public suspend fun TelegramBot.sendGift(
user: User,
gift: Gift,
text: String,
parseMode: ParseMode?
): Boolean = sendGift(
user.id,
gift.id,
text,
parseMode
)
public suspend fun TelegramBot.sendGift(
user: User,
gift: Gift,
textSources: TextSourcesList,
): Boolean = sendGift(
user.id,
gift.id,
textSources
)

View File

@ -0,0 +1,17 @@
package dev.inmo.tgbotapi.requests.gifts
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.gifts.Gifts
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy
@Serializable
data object GetAvailableGifts : SimpleRequest<Gifts> {
override fun method(): String = "getAvailableGifts"
override val resultDeserializer: DeserializationStrategy<Gifts>
get() = Gifts.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -0,0 +1,57 @@
package dev.inmo.tgbotapi.requests.gifts
import dev.inmo.tgbotapi.abstracts.TextedOutput
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.RawMessageEntity
import dev.inmo.tgbotapi.types.message.asTextSources
import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
import dev.inmo.tgbotapi.types.message.toRawMessageEntities
import dev.inmo.tgbotapi.utils.extensions.makeSourceString
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.builtins.serializer
@Serializable
data class SendGift internal constructor(
@SerialName(userIdField)
val userId: UserId,
@SerialName(giftIdField)
val giftId: GiftId,
@SerialName(textField)
override val text: String,
@SerialName(textParseModeField)
override val parseMode: ParseMode?,
@SerialName(entitiesField)
private val rawEntities: List<RawMessageEntity>? = null,
) : SimpleRequest<Boolean>, TextedOutput {
override val textSources: TextSourcesList? by lazy {
rawEntities ?.asTextSources(text)
}
override fun method(): String = "sendGift"
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()
constructor(
userId: UserId,
giftId: GiftId,
text: String,
parseMode: ParseMode?
) : this(userId, giftId, text, parseMode, null)
constructor(
userId: UserId,
giftId: GiftId,
textSources: TextSourcesList,
) : this(userId, giftId, textSources.makeSourceString(), null, textSources.toRawMessageEntities())
}

View File

@ -34,6 +34,12 @@ value class PaidMediaPayload(val string: String) {
}
}
@Serializable
@JvmInline
value class GiftId(
val string: String
)
val usernameRegex = Regex("@[\\w\\d_]+")
val degreesLimit = 1 .. 360
@ -190,6 +196,7 @@ const val maskPositionField = "mask_position"
const val phoneNumberField = "phone_number"
const val userIdField = "user_id"
const val userIdsField = "user_ids"
const val giftIdField = "gift_id"
const val onlyIfBannedField = "only_if_banned"
const val containsMasksField = "contains_masks"
const val resultIdField = "result_id"
@ -472,6 +479,8 @@ const val creatorField = "creator"
const val subscriptionPeriodField = "subscription_period"
const val subscriptionPriceField = "subscription_price"
const val copyTextField = "copy_text"
const val giftField = "gift"
const val giftsField = "gifts"
const val pointField = "point"
const val xShiftField = "x_shift"
@ -512,6 +521,7 @@ const val shippingOptionsField = "shipping_options"
const val countryCodeField = "country_code"
const val countryCodesField = "country_codes"
const val totalCountField = "total_count"
const val remainingCountField = "remaining_count"
const val stateField = "state"
const val cityField = "city"
const val firstStreetLineField = "street_line1"

View File

@ -0,0 +1,92 @@
package dev.inmo.tgbotapi.types.gifts
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.files.Sticker
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializable(Gift.Companion::class)
sealed interface Gift {
val id: GiftId
val sticker: Sticker
val starCount: Int
val totalCount: Int?
val remainingCount: Int?
@Serializable
data class Unlimited(
@SerialName(idField)
override val id: GiftId,
@SerialName(stickerField)
override val sticker: Sticker,
@SerialName(starCountField)
override val starCount: Int
) : Gift {
override val totalCount: Int?
get() = null
override val remainingCount: Int?
get() = null
}
@Serializable
data class Limited(
@SerialName(idField)
override val id: GiftId,
@SerialName(stickerField)
override val sticker: Sticker,
@SerialName(starCountField)
override val starCount: Int,
@SerialName(totalCountField)
override val totalCount: Int,
@SerialName(remainingCountField)
override val remainingCount: Int,
) : Gift
companion object : KSerializer<Gift> {
@Serializable
private data class GiftSurrogate(
val id: GiftId,
val sticker: Sticker,
val star_count: Int,
val total_count: Int? = null,
val remaining_count: Int? = null,
)
override val descriptor: SerialDescriptor
get() = GiftSurrogate.serializer().descriptor
override fun deserialize(decoder: Decoder): Gift {
val surrogate = GiftSurrogate.serializer().deserialize(decoder)
return if (surrogate.total_count != null && surrogate.remaining_count != null) {
Limited(
surrogate.id,
surrogate.sticker,
surrogate.star_count,
surrogate.total_count,
surrogate.remaining_count
)
} else {
Unlimited(
surrogate.id,
surrogate.sticker,
surrogate.star_count,
)
}
}
override fun serialize(encoder: Encoder, value: Gift) {
val surrogate = GiftSurrogate(
value.id,
value.sticker,
value.starCount,
value.totalCount,
value.remainingCount
)
}
}
}

View File

@ -0,0 +1,11 @@
package dev.inmo.tgbotapi.types.gifts
import dev.inmo.tgbotapi.types.giftsField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Gifts(
@SerialName(giftsField)
val gifts: List<Gift>
)

View File

@ -4,6 +4,7 @@ package dev.inmo.tgbotapi.types.payments.stars
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.PreviewUser
import dev.inmo.tgbotapi.types.gifts.Gift
import dev.inmo.tgbotapi.types.message.payments.PaidMedia
import dev.inmo.tgbotapi.utils.decodeDataAndJson
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
@ -45,7 +46,9 @@ sealed interface TransactionPartner {
@SerialName(paidMediaField)
val paidMedia: List<PaidMedia>? = null,
@SerialName(paidMediaPayloadField)
val paidMediaPayload: PaidMediaPayload? = null
val paidMediaPayload: PaidMediaPayload? = null,
@SerialName(giftField)
val gift: Gift? = null
) : TransactionPartner {
@EncodeDefault
override val type: String = Companion.type