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

add support of ChatBackground

This commit is contained in:
InsanusMokrassar 2024-05-09 21:54:24 +06:00
parent 7e986b2088
commit 97621bca67
12 changed files with 566 additions and 0 deletions

View File

@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.chat.ChatBackground
import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed
@ -219,3 +220,8 @@ suspend fun BehaviourContext.waitChatBoostAdded(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<ChatBoostAdded>(initRequest, errorFactory)
suspend fun BehaviourContext.waitChatBackgroundSet(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<ChatBackground>(initRequest, errorFactory)

View File

@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.chat.ChatBackground
import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed
@ -213,3 +214,8 @@ suspend fun BehaviourContext.waitChatBoostAddedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ChatBoostAdded>(initRequest, errorFactory)
suspend fun BehaviourContext.waitChatBackgroundSetEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ChatBackground>(initRequest, errorFactory)

View File

@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.Mar
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.chatEventMessageOrNull
import dev.inmo.tgbotapi.types.chat.ChatBackground
import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed
@ -844,3 +845,23 @@ suspend fun <BC : BehaviourContext> BC.onChatBoostAdded(
markerFactory: MarkerFactory<in ChatEventMessage<ChatBoostAdded>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<ChatBoostAdded>>
) = 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.onChatBackgroundSet(
initialFilter: SimpleFilter<ChatEventMessage<ChatBackground>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<ChatBackground>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<ChatBackground>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<ChatBackground>>
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@ -0,0 +1,128 @@
package dev.inmo.tgbotapi.types
import dev.inmo.micro_utils.colors.common.HEXAColor
import dev.inmo.tgbotapi.utils.IntRGB24HEXAColorSerializer
import dev.inmo.tgbotapi.utils.extractDataAndJson
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.decodeFromJsonElement
@ClassCastsIncluded
@Serializable(BackgroundFill.Companion::class)
sealed interface BackgroundFill {
val type: String
val colors: List<HEXAColor>
@Serializable
data class Solid(
@SerialName(colorField)
@Serializable(IntRGB24HEXAColorSerializer::class)
val color: HEXAColor
) : BackgroundFill {
@Transient
override val colors: List<HEXAColor> = listOf(color)
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type = "solid"
}
}
@Serializable
data class Gradient(
@SerialName(topColorField)
@Serializable(IntRGB24HEXAColorSerializer::class)
val topColor: HEXAColor,
@SerialName(bottomColorField)
@Serializable(IntRGB24HEXAColorSerializer::class)
val bottomColor: HEXAColor,
@SerialName(rotationAngleField)
val rotationAngle: Short,
) : BackgroundFill {
@Transient
override val colors: List<HEXAColor> = listOf(topColor, bottomColor)
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type = "gradient"
}
}
@Serializable
data class FreeformGradient(
@SerialName(colorsField)
override val colors: List<@Serializable(IntRGB24HEXAColorSerializer::class) HEXAColor>
) : BackgroundFill {
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type = "freeform_gradient"
}
}
@Serializable
data class Unknown(
override val type: String,
val raw: JsonElement?
) : BackgroundFill {
@SerialName(colorsField)
override val colors: List<HEXAColor> = emptyList()
}
companion object : KSerializer<BackgroundFill> {
@Serializable
class RawBackgroundFill private constructor(
@SerialName(typeField)
val type: String,
@Serializable(IntRGB24HEXAColorSerializer::class)
val color: HEXAColor? = null,
@SerialName(topColorField)
@Serializable(IntRGB24HEXAColorSerializer::class)
val topColor: HEXAColor? = null,
@SerialName(bottomColorField)
@Serializable(IntRGB24HEXAColorSerializer::class)
val bottomColor: HEXAColor? = null,
@SerialName(rotationAngleField)
val rotationAngle: Short? = null,
@SerialName(colorsField)
val colors: List<@Serializable(IntRGB24HEXAColorSerializer::class) HEXAColor>? = null
)
private val serializer = RawBackgroundFill.serializer()
override val descriptor: SerialDescriptor
get() = serializer.descriptor
override fun deserialize(decoder: Decoder): BackgroundFill {
val (raw, json) = decoder.extractDataAndJson(serializer)
return when (raw.type) {
Solid.type -> Solid(color = raw.color ?: return Unknown(raw.type, json))
Gradient.type -> Gradient(
topColor = raw.topColor ?: return Unknown(raw.type, json),
bottomColor = raw.bottomColor ?: return Unknown(raw.type, json),
rotationAngle = raw.rotationAngle ?: return Unknown(raw.type, json)
)
FreeformGradient.type -> FreeformGradient(raw.colors ?: return Unknown(raw.type, json))
else -> Unknown(raw.type, json)
}
}
override fun serialize(encoder: Encoder, value: BackgroundFill) {
when (value) {
is FreeformGradient -> FreeformGradient.serializer().serialize(encoder, value)
is Gradient -> Gradient.serializer().serialize(encoder, value)
is Solid -> Solid.serializer().serialize(encoder, value)
is Unknown -> value.raw ?.also {
JsonElement.serializer().serialize(encoder, it)
} ?: Unknown.serializer().serialize(encoder, value)
}
}
}
}

View File

@ -0,0 +1,180 @@
package dev.inmo.tgbotapi.types
import dev.inmo.micro_utils.common.Progress
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.utils.IntProgress100Serializer
import dev.inmo.tgbotapi.utils.extractDataAndJson
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import kotlinx.serialization.EncodeDefault
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
import kotlinx.serialization.json.JsonElement
@ClassCastsIncluded
@Serializable(BackgroundType.Companion::class)
sealed interface BackgroundType {
val type: String
sealed interface Movable : BackgroundType {
val isMoving: Boolean
}
sealed interface Dimmable : BackgroundType {
val darkThemeDimming: Progress
}
sealed interface Fillable : BackgroundType {
val fill: BackgroundFill
}
sealed interface WithDocument : BackgroundType {
val document: DocumentFile
}
@Serializable
data class Fill(
@SerialName(fillField)
override val fill: BackgroundFill,
@SerialName(darkThemeDimmingField)
@Serializable(IntProgress100Serializer::class)
override val darkThemeDimming: Progress
) : Fillable, Dimmable {
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type: String = "fill"
}
}
@Serializable
data class Wallpaper(
@SerialName(documentField)
override val document: DocumentFile,
@SerialName(darkThemeDimmingField)
@Serializable(IntProgress100Serializer::class)
override val darkThemeDimming: Progress,
@SerialName(isBlurredField)
val isBlurred: Boolean = false,
@SerialName(isMovingField)
override val isMoving: Boolean = false
) : WithDocument, Dimmable, Movable {
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type: String = "wallpaper"
}
}
@Serializable
data class Pattern(
@SerialName(documentField)
override val document: DocumentFile,
@SerialName(fillField)
override val fill: BackgroundFill,
@SerialName(intensityField)
@Serializable(IntProgress100Serializer::class)
val intensity: Progress,
@SerialName(isInvertedField)
val isInverted: Boolean = false,
@SerialName(isMovingField)
override val isMoving: Boolean = false
) : WithDocument, Fillable, Movable {
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type: String = "pattern"
}
}
@Serializable
data class ChatTheme(
@SerialName(themeNameField)
val themeName: String
): BackgroundType {
@EncodeDefault
@SerialName(typeField)
override val type: String = Companion.type
companion object {
const val type: String = "chat_theme"
}
}
@Serializable
data class Unknown(
@SerialName(typeField)
override val type: String,
val raw: JsonElement?
): BackgroundType
companion object : KSerializer<BackgroundType> {
@Serializable
data class RawBackgroundType(
val type: String,
@SerialName(fillField)
val fill: BackgroundFill? = null,
@SerialName(darkThemeDimmingField)
@Serializable(IntProgress100Serializer::class)
val darkThemeDimming: Progress? = null,
@SerialName(documentField)
val document: DocumentFile? = null,
@SerialName(isBlurredField)
val isBlurred: Boolean = false,
@SerialName(isMovingField)
val isMoving: Boolean = false,
@SerialName(intensityField)
@Serializable(IntProgress100Serializer::class)
val intensity: Progress? = null,
@SerialName(isInvertedField)
val isInverted: Boolean = false,
@SerialName(themeNameField)
val themeName: String? = null
)
override val descriptor: SerialDescriptor
get() = RawBackgroundType.serializer().descriptor
override fun deserialize(decoder: Decoder): BackgroundType {
val (raw, json) = decoder.extractDataAndJson(RawBackgroundType.serializer())
val unknown by lazy { Unknown(raw.type, json) }
return when (raw.type) {
Fill.type -> Fill(
raw.fill ?: return unknown,
raw.darkThemeDimming ?: return unknown
)
Wallpaper.type -> Wallpaper(
document = raw.document ?: return unknown,
darkThemeDimming = raw.darkThemeDimming ?: return unknown,
isBlurred = raw.isBlurred,
isMoving = raw.isMoving
)
Pattern.type -> Pattern(
document = raw.document ?: return unknown,
fill = raw.fill ?: return unknown,
intensity = raw.intensity ?: return unknown,
isInverted = raw.isInverted,
isMoving = raw.isMoving
)
ChatTheme.type -> ChatTheme(
raw.themeName ?: return unknown
)
else -> unknown
}
}
override fun serialize(encoder: Encoder, value: BackgroundType) {
when (value) {
is ChatTheme -> ChatTheme.serializer().serialize(encoder, value)
is Fill -> Fill.serializer().serialize(encoder, value)
is Wallpaper -> Wallpaper.serializer().serialize(encoder, value)
is Pattern -> Pattern.serializer().serialize(encoder, value)
is Unknown -> value.raw ?.also {
JsonElement.serializer().serialize(encoder, it)
} ?: Unknown.serializer().serialize(encoder, value)
}
}
}
}

View File

@ -604,6 +604,20 @@ const val businessIntroField = "business_intro"
const val businessLocationField = "business_location"
const val businessOpeningHoursField = "business_opening_hours"
const val colorField = "color"
const val colorsField = "colors"
const val topColorField = "top_color"
const val bottomColorField = "bottom_color"
const val rotationAngleField = "rotation_angle"
const val fillField = "fill"
const val darkThemeDimmingField = "dark_theme_dimming"
const val isBlurredField = "is_blurred"
const val isInvertedField = "is_inverted"
const val isMovingField = "is_moving"
const val intensityField = "intensity"
const val themeNameField = "theme_name"
const val dayField = "day"
const val monthField = "month"
const val yearField = "year"

View File

@ -0,0 +1,13 @@
package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.types.BackgroundType
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent
import dev.inmo.tgbotapi.types.typeField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ChatBackground(
@SerialName(typeField)
val type: BackgroundType
) : CommonEvent

View File

@ -125,6 +125,9 @@ internal data class RawMessage(
// Boost added to groups
private val boost_added: ChatBoostAdded? = null,
// Chat background has been changed
private val chat_background_set: ChatBackground? = null,
// AutoDelete Message time changed
private val message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? = null,
@ -260,6 +263,7 @@ internal data class RawMessage(
giveaway_winners is GiveawayPrivateResults -> giveaway_winners
giveaway_completed != null -> giveaway_completed
boost_added != null -> boost_added
chat_background_set != null -> chat_background_set
else -> null
}
}

View File

@ -0,0 +1,15 @@
package dev.inmo.tgbotapi.utils
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonElement
fun <T> Decoder.extractDataAndJson(serializer: DeserializationStrategy<T>): Pair<T, JsonElement?> {
return if (this is JsonDecoder) {
val raw = decodeJsonElement()
json.decodeFromJsonElement(serializer, raw) to raw
} else {
serializer.deserialize(this) to null
}
}

View File

@ -0,0 +1,27 @@
package dev.inmo.tgbotapi.utils
import dev.inmo.micro_utils.common.Progress
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
object IntProgress100Serializer : KSerializer<Progress> {
override val descriptor: SerialDescriptor
get() = Int.serializer().descriptor
override fun deserialize(decoder: Decoder): Progress {
return Progress(
decoder.decodeInt(),
100
)
}
override fun serialize(encoder: Encoder, value: Progress) {
encoder.encodeInt(
value.of100Int
)
}
}

View File

@ -0,0 +1,22 @@
package dev.inmo.tgbotapi.utils
import dev.inmo.micro_utils.colors.common.HEXAColor
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
object IntRGB24HEXAColorSerializer : KSerializer<HEXAColor> {
override val descriptor: SerialDescriptor
get() = Int.serializer().descriptor
override fun deserialize(decoder: Decoder): HEXAColor {
val raw = decoder.decodeInt()
return HEXAColor(raw.shl(2).toUInt() + 0xffu)
}
override fun serialize(encoder: Encoder, value: HEXAColor) {
encoder.encodeInt(value.rgbInt)
}
}

View File

@ -16,6 +16,8 @@ import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton
import dev.inmo.tgbotapi.requests.send.payments.CreateInvoiceLink
import dev.inmo.tgbotapi.requests.send.payments.SendInvoice
import dev.inmo.tgbotapi.requests.stickers.InputSticker
import dev.inmo.tgbotapi.types.BackgroundFill
import dev.inmo.tgbotapi.types.BackgroundType
import dev.inmo.tgbotapi.types.BusinessChatId
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.ChatIdWithThreadId
@ -116,6 +118,7 @@ import dev.inmo.tgbotapi.types.chat.Bot
import dev.inmo.tgbotapi.types.chat.BusinessChat
import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.ChatBackground
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated
import dev.inmo.tgbotapi.types.chat.CommonBot
@ -1088,6 +1091,124 @@ public inline fun InputSticker.regularOrThrow(): InputSticker.WithKeywords.Regul
public inline fun <T> InputSticker.ifRegular(block: (InputSticker.WithKeywords.Regular) -> T): T? =
regularOrNull() ?.let(block)
public inline fun BackgroundFill.freeformGradientOrNull(): BackgroundFill.FreeformGradient? = this
as? dev.inmo.tgbotapi.types.BackgroundFill.FreeformGradient
public inline fun BackgroundFill.freeformGradientOrThrow(): BackgroundFill.FreeformGradient = this
as dev.inmo.tgbotapi.types.BackgroundFill.FreeformGradient
public inline fun <T>
BackgroundFill.ifFreeformGradient(block: (BackgroundFill.FreeformGradient) -> T): T? =
freeformGradientOrNull() ?.let(block)
public inline fun BackgroundFill.gradientOrNull(): BackgroundFill.Gradient? = this as?
dev.inmo.tgbotapi.types.BackgroundFill.Gradient
public inline fun BackgroundFill.gradientOrThrow(): BackgroundFill.Gradient = this as
dev.inmo.tgbotapi.types.BackgroundFill.Gradient
public inline fun <T> BackgroundFill.ifGradient(block: (BackgroundFill.Gradient) -> T): T? =
gradientOrNull() ?.let(block)
public inline fun BackgroundFill.solidOrNull(): BackgroundFill.Solid? = this as?
dev.inmo.tgbotapi.types.BackgroundFill.Solid
public inline fun BackgroundFill.solidOrThrow(): BackgroundFill.Solid = this as
dev.inmo.tgbotapi.types.BackgroundFill.Solid
public inline fun <T> BackgroundFill.ifSolid(block: (BackgroundFill.Solid) -> T): T? = solidOrNull()
?.let(block)
public inline fun BackgroundFill.unknownOrNull(): BackgroundFill.Unknown? = this as?
dev.inmo.tgbotapi.types.BackgroundFill.Unknown
public inline fun BackgroundFill.unknownOrThrow(): BackgroundFill.Unknown = this as
dev.inmo.tgbotapi.types.BackgroundFill.Unknown
public inline fun <T> BackgroundFill.ifUnknown(block: (BackgroundFill.Unknown) -> T): T? =
unknownOrNull() ?.let(block)
public inline fun BackgroundType.chatThemeOrNull(): BackgroundType.ChatTheme? = this as?
dev.inmo.tgbotapi.types.BackgroundType.ChatTheme
public inline fun BackgroundType.chatThemeOrThrow(): BackgroundType.ChatTheme = this as
dev.inmo.tgbotapi.types.BackgroundType.ChatTheme
public inline fun <T> BackgroundType.ifChatTheme(block: (BackgroundType.ChatTheme) -> T): T? =
chatThemeOrNull() ?.let(block)
public inline fun BackgroundType.dimmableOrNull(): BackgroundType.Dimmable? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Dimmable
public inline fun BackgroundType.dimmableOrThrow(): BackgroundType.Dimmable = this as
dev.inmo.tgbotapi.types.BackgroundType.Dimmable
public inline fun <T> BackgroundType.ifDimmable(block: (BackgroundType.Dimmable) -> T): T? =
dimmableOrNull() ?.let(block)
public inline fun BackgroundType.fillOrNull(): BackgroundType.Fill? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Fill
public inline fun BackgroundType.fillOrThrow(): BackgroundType.Fill = this as
dev.inmo.tgbotapi.types.BackgroundType.Fill
public inline fun <T> BackgroundType.ifFill(block: (BackgroundType.Fill) -> T): T? = fillOrNull()
?.let(block)
public inline fun BackgroundType.wallpaperOrNull(): BackgroundType.Wallpaper? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Wallpaper
public inline fun BackgroundType.wallpaperOrThrow(): BackgroundType.Wallpaper = this as
dev.inmo.tgbotapi.types.BackgroundType.Wallpaper
public inline fun <T> BackgroundType.ifWallpaper(block: (BackgroundType.Wallpaper) -> T): T? =
wallpaperOrNull() ?.let(block)
public inline fun BackgroundType.fillableOrNull(): BackgroundType.Fillable? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Fillable
public inline fun BackgroundType.fillableOrThrow(): BackgroundType.Fillable = this as
dev.inmo.tgbotapi.types.BackgroundType.Fillable
public inline fun <T> BackgroundType.ifFillable(block: (BackgroundType.Fillable) -> T): T? =
fillableOrNull() ?.let(block)
public inline fun BackgroundType.patternOrNull(): BackgroundType.Pattern? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Pattern
public inline fun BackgroundType.patternOrThrow(): BackgroundType.Pattern = this as
dev.inmo.tgbotapi.types.BackgroundType.Pattern
public inline fun <T> BackgroundType.ifPattern(block: (BackgroundType.Pattern) -> T): T? =
patternOrNull() ?.let(block)
public inline fun BackgroundType.movableOrNull(): BackgroundType.Movable? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Movable
public inline fun BackgroundType.movableOrThrow(): BackgroundType.Movable = this as
dev.inmo.tgbotapi.types.BackgroundType.Movable
public inline fun <T> BackgroundType.ifMovable(block: (BackgroundType.Movable) -> T): T? =
movableOrNull() ?.let(block)
public inline fun BackgroundType.unknownOrNull(): BackgroundType.Unknown? = this as?
dev.inmo.tgbotapi.types.BackgroundType.Unknown
public inline fun BackgroundType.unknownOrThrow(): BackgroundType.Unknown = this as
dev.inmo.tgbotapi.types.BackgroundType.Unknown
public inline fun <T> BackgroundType.ifUnknown(block: (BackgroundType.Unknown) -> T): T? =
unknownOrNull() ?.let(block)
public inline fun BackgroundType.withDocumentOrNull(): BackgroundType.WithDocument? = this as?
dev.inmo.tgbotapi.types.BackgroundType.WithDocument
public inline fun BackgroundType.withDocumentOrThrow(): BackgroundType.WithDocument = this as
dev.inmo.tgbotapi.types.BackgroundType.WithDocument
public inline fun <T> BackgroundType.ifWithDocument(block: (BackgroundType.WithDocument) -> T): T? =
withDocumentOrNull() ?.let(block)
public inline fun ChatIdentifier.idChatIdentifierOrNull(): IdChatIdentifier? = this as?
dev.inmo.tgbotapi.types.IdChatIdentifier
@ -2943,6 +3064,15 @@ public inline fun TelegramMedia.titledTelegramMediaOrThrow(): TitledTelegramMedi
public inline fun <T> TelegramMedia.ifTitledTelegramMedia(block: (TitledTelegramMedia) -> T): T? =
titledTelegramMediaOrNull() ?.let(block)
public inline fun ChatEvent.chatBackgroundOrNull(): ChatBackground? = this as?
dev.inmo.tgbotapi.types.chat.ChatBackground
public inline fun ChatEvent.chatBackgroundOrThrow(): ChatBackground = this as
dev.inmo.tgbotapi.types.chat.ChatBackground
public inline fun <T> ChatEvent.ifChatBackground(block: (ChatBackground) -> T): T? =
chatBackgroundOrNull() ?.let(block)
public inline fun ChatEvent.giveawayCreatedOrNull(): GiveawayCreated? = this as?
dev.inmo.tgbotapi.types.giveaway.GiveawayCreated