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 56c7b39add..cf884c0b4b 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 @@ -491,6 +491,7 @@ const val isBigField = "is_big" const val oldReactionField = "old_reaction" const val newReactionField = "new_reaction" const val chatField = "chat" +const val originField = "origin" const val chatsField = "chats" const val usernameField = "username" const val bioField = "bio" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Contact.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Contact.kt index 1e11d16ad3..b84d4ed72a 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Contact.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Contact.kt @@ -16,4 +16,4 @@ data class Contact( val userId: UserId? = null, @SerialName(vcardField) override val vcard: String? = null -) : CommonContactData +) : CommonContactData, ExternalReplyInfo.ContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ExternalReplyInfo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ExternalReplyInfo.kt new file mode 100644 index 0000000000..7bf46b0d48 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ExternalReplyInfo.kt @@ -0,0 +1,166 @@ +package dev.inmo.tgbotapi.types + +import dev.inmo.tgbotapi.abstracts.SpoilerableData +import dev.inmo.tgbotapi.types.chat.SuperPublicChat +import dev.inmo.tgbotapi.types.dice.Dice +import dev.inmo.tgbotapi.types.files.* +import dev.inmo.tgbotapi.types.games.Game +import dev.inmo.tgbotapi.types.games.RawGame +import dev.inmo.tgbotapi.types.giveaway.GiveawayPublicResults +import dev.inmo.tgbotapi.types.giveaway.ScheduledGiveaway +import dev.inmo.tgbotapi.types.location.Location +import dev.inmo.tgbotapi.types.message.MessageOrigin +import dev.inmo.tgbotapi.types.message.abstracts.Message +import dev.inmo.tgbotapi.types.payments.Invoice +import dev.inmo.tgbotapi.types.polls.Poll +import dev.inmo.tgbotapi.types.stories.Story +import dev.inmo.tgbotapi.types.venue.Venue +import dev.inmo.tgbotapi.utils.RiskFeature +import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded +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(ExternalReplyInfo.Companion::class) +@ClassCastsIncluded +sealed interface ExternalReplyInfo { + val origin: MessageOrigin + val chat: SuperPublicChat? + val messageMeta: Message.MetaInfo? + + interface ContentVariant + + @Serializable + data class Text( + override val origin: MessageOrigin, + override val chat: SuperPublicChat?, + override val messageMeta: Message.MetaInfo?, + val linkPreviewOptions: LinkPreviewOptions? + ) : ExternalReplyInfo + + @Serializable(ExternalReplyInfo.Companion::class) + sealed interface Content : ExternalReplyInfo { + val content: ContentVariant + + + @Serializable + data class Simple( + override val origin: MessageOrigin, + override val chat: SuperPublicChat?, + override val messageMeta: Message.MetaInfo?, + override val content: ContentVariant + ) : Content + + @Serializable + data class Media( + override val origin: MessageOrigin, + override val chat: SuperPublicChat?, + override val messageMeta: Message.MetaInfo?, + override val spoilered: Boolean, + override val content: T + ) : Content, SpoilerableData where T: ContentVariant, T : TelegramMediaFile + } + + @Serializable + private data class Surrogate( + val origin: MessageOrigin, + val chat: SuperPublicChat? = null, + val message_id: MessageId? = null, + val link_preview_options: LinkPreviewOptions? = null, + val has_media_spoiler: Boolean? = null, + private val story: Story? = null, + private val audio: AudioFile? = null, + private val document: DocumentFile? = null, + private val animation: AnimationFile? = null, + private val game: RawGame? = null, + @Serializable(PhotoSerializer::class) + private val photo: Photo? = null, + private val sticker: Sticker? = null, + private val video: VideoFile? = null, + private val voice: VoiceFile? = null, + private val video_note: VideoNoteFile? = null, + private val contact: Contact? = null, + private val location: Location? = null, + private val venue: Venue? = null, + private val poll: Poll? = null, + private val invoice: Invoice? = null, + private val dice: Dice? = null, + private val giveaway: ScheduledGiveaway? = null, + private val giveaway_winners: GiveawayPublicResults? = null, + ) { + val asExternalReplyInfo: ExternalReplyInfo + get() { + val messageMeta = chat ?.let { + message_id ?.let { + Message.MetaInfo( + chat.id, + message_id + ) + } + } + val content: ContentVariant? = when { + story != null -> story + audio != null -> audio + video != null -> video + video_note != null -> video_note + animation != null -> animation + document != null -> document + voice != null -> voice + photo != null -> photo + sticker != null -> sticker + dice != null -> dice + game != null -> game.asGame + contact != null -> contact + location != null -> location + venue != null -> venue + poll != null -> poll + invoice != null -> invoice + giveaway != null -> giveaway + giveaway_winners != null -> giveaway_winners + else -> null + } + + return content ?.let { + when (it) { + is TelegramMediaFile -> { + Content.Media( + origin, + chat, + messageMeta, + has_media_spoiler == true, + it + ) + } + else -> Content.Simple( + origin, + chat, + messageMeta, + it + ) + } + } ?: Text( + origin, + chat, + messageMeta, + link_preview_options + ) + } + } + + @RiskFeature("This serializer currently support only deserialization, but not serialization") + companion object : KSerializer { + override val descriptor: SerialDescriptor + get() = Surrogate.serializer().descriptor + + override fun deserialize(decoder: Decoder): ExternalReplyInfo { + return Surrogate.serializer().deserialize(decoder).asExternalReplyInfo + } + + override fun serialize(encoder: Encoder, value: ExternalReplyInfo) { + + } + } +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/dice/Dice.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/dice/Dice.kt index 834df0c729..c5a70ff3f3 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/dice/Dice.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/dice/Dice.kt @@ -10,4 +10,4 @@ data class Dice( val value: DiceResult, @SerialName(emojiField) val animationType: DiceAnimationType -) +) : ExternalReplyInfo.ContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AnimationFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AnimationFile.kt index 6492f43f39..d09fbcbe79 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AnimationFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AnimationFile.kt @@ -23,4 +23,5 @@ data class AnimationFile( override val mimeType: MimeType? = null, @SerialName(fileSizeField) override val fileSize: Long? = null -) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, CustomNamedMediaFile, SizedMediaFile +) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, CustomNamedMediaFile, SizedMediaFile, + ExternalReplyInfo.ContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AudioFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AudioFile.kt index e8a85ac00b..c83351dc25 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AudioFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/AudioFile.kt @@ -28,6 +28,6 @@ data class AudioFile( @SerialName(thumbnailField) override val thumbnail: PhotoSize? = null ) : TelegramMediaFile, CustomNamedMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, TitledMediaFile, - Performerable + Performerable, ExternalReplyInfo.ContentVariant fun AudioFile.asVoiceFile() = VoiceFile(fileId, fileUniqueId, duration, mimeType, fileSize) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt index f2b57fe6a7..73df323628 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt @@ -20,7 +20,7 @@ data class DocumentFile( override val mimeType: MimeType? = null, @SerialName(fileNameField) override val fileName: String? = null -) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, CustomNamedMediaFile +) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, CustomNamedMediaFile, ExternalReplyInfo.ContentVariant @Suppress("NOTHING_TO_INLINE") inline fun TelegramMediaFile.asDocumentFile() = if (this is DocumentFile) { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt index 707eed7e2d..39bd5c42cf 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt @@ -6,17 +6,20 @@ import dev.inmo.tgbotapi.types.files.* import dev.inmo.tgbotapi.utils.RiskFeature import kotlinx.serialization.* import kotlinx.serialization.builtins.ListSerializer +import kotlin.jvm.JvmInline -typealias Photo = List +@Serializable +@JvmInline +value class Photo( + val photos: List +) : List by photos, ExternalReplyInfo.ContentVariant fun Photo.biggest(): PhotoSize? = maxByOrNull { it.resolution } @RiskFeature -object PhotoSerializer : KSerializer by ListSerializer( - PhotoSize.serializer() -) +object PhotoSerializer : KSerializer by Photo.serializer() @Serializable data class PhotoSize( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/Sticker.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/Sticker.kt index b05bb06971..4355de3241 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/Sticker.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/Sticker.kt @@ -34,7 +34,7 @@ data class StickerSurrogate( // TODO:: Serializer @Serializable(StickerSerializer::class) -sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile { +sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile, ExternalReplyInfo.ContentVariant { val emoji: String? val stickerSetName: StickerSetName? val stickerFormat: StickerFormat diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt index 3fbc99a402..5eec4d48a7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt @@ -29,7 +29,8 @@ data class VideoFile( override val mimeType: MimeType? = null, @SerialName(fileSizeField) override val fileSize: Long? = null -) : TelegramMediaFile, CustomNamedMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile +) : TelegramMediaFile, CustomNamedMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile, + ExternalReplyInfo.ContentVariant @Suppress("NOTHING_TO_INLINE") inline fun VideoFile.toTelegramMediaVideo( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoNoteFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoNoteFile.kt index d98d872261..49b5ec8889 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoNoteFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoNoteFile.kt @@ -18,7 +18,7 @@ data class VideoNoteFile( override val thumbnail: PhotoSize? = null, @SerialName(fileSizeField) override val fileSize: Long? = null -) : TelegramMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile { +) : TelegramMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile, ExternalReplyInfo.ContentVariant { override val height: Int get() = width } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VoiceFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VoiceFile.kt index f3a88b1e66..725a52a0ed 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VoiceFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VoiceFile.kt @@ -19,7 +19,7 @@ data class VoiceFile( override val mimeType: MimeType? = null, @SerialName(fileSizeField) override val fileSize: Long? = null -) : TelegramMediaFile, MimedMediaFile, PlayableMediaFile +) : TelegramMediaFile, MimedMediaFile, PlayableMediaFile, ExternalReplyInfo.ContentVariant fun VoiceFile.asAudioFile( performer: String? = null, diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/Game.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/Game.kt index bf908d161f..60027bc169 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/Game.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/Game.kt @@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.games import dev.inmo.tgbotapi.abstracts.TextedInput import dev.inmo.tgbotapi.abstracts.Titled +import dev.inmo.tgbotapi.types.ExternalReplyInfo import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList import dev.inmo.tgbotapi.types.files.AnimationFile import dev.inmo.tgbotapi.types.files.Photo @@ -15,4 +16,4 @@ data class Game( override val text: String? = null, override val textSources: TextSourcesList = emptyList(), val animation: AnimationFile? = null -) : Titled, TextedInput +) : Titled, TextedInput, ExternalReplyInfo.ContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt index 85e9b9a5f6..83fe74fa2f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt @@ -13,7 +13,8 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder @Serializable(GiveawayPublicResults.Companion::class) -sealed interface GiveawayPublicResults: GiveawayInfo, GiveawayResults, WithPreviewChatAndMessageId { +sealed interface GiveawayPublicResults: GiveawayInfo, GiveawayResults, WithPreviewChatAndMessageId, + ExternalReplyInfo.ContentVariant { val count: Int val winners: List val additionalChats: Int diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/ScheduledGiveaway.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/ScheduledGiveaway.kt index d0642619f0..317a83287e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/ScheduledGiveaway.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/ScheduledGiveaway.kt @@ -30,4 +30,4 @@ data class ScheduledGiveaway( val countries: List? = null, @SerialName(premiumSubscriptionMonthCountField) override val premiumMonths: Int? = null -) : GiveawayInfo \ No newline at end of file +) : GiveawayInfo, ExternalReplyInfo.ContentVariant \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/location/Location.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/location/Location.kt index 423c208121..149f04c533 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/location/Location.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/location/Location.kt @@ -20,7 +20,7 @@ import kotlinx.serialization.json.JsonObject */ @Serializable(LocationSerializer::class) @ClassCastsIncluded -sealed interface Location : Locationed, HorizontallyAccured +sealed interface Location : Locationed, HorizontallyAccured, ExternalReplyInfo.ContentVariant @Serializable data class StaticLocation( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt index e8758b9045..087df83da7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt @@ -94,6 +94,8 @@ internal data class RawMessage( private val invoice: Invoice? = null, private val dice: Dice? = null, private val successful_payment: SuccessfulPayment? = null, + private val giveaway: ScheduledGiveaway? = null, + private val giveaway_winners: GiveawayResults? = null, private val users_shared: UsersShared? = null, private val chat_shared: ChatShared? = null, @@ -132,8 +134,6 @@ internal data class RawMessage( // Giveaways private val giveaway_created: GiveawayCreated? = null, - private val giveaway: ScheduledGiveaway? = null, - private val giveaway_winners: GiveawayResults? = null, private val giveaway_completed: GiveawayPrivateResults? = null, ) { private val content: MessageContent? by lazy { @@ -177,7 +177,7 @@ internal data class RawMessage( adaptedCaptionEntities ) photo != null -> PhotoContent( - photo.toList(), + photo, caption, adaptedCaptionEntities, has_media_spoiler ?: false @@ -191,7 +191,7 @@ internal data class RawMessage( venue != null -> VenueContent(venue) poll != null -> PollContent(poll) invoice != null -> InvoiceContent(invoice) - giveaway != null -> ScheduledGiveawayContent(giveaway) + giveaway != null -> ScheduledGiveawayContent(chat, messageId, giveaway) giveaway_winners is GiveawayPublicResults -> GiveawayPublicResultsContent(giveaway_winners) else -> null } @@ -202,7 +202,7 @@ internal data class RawMessage( new_chat_members != null -> NewChatMembers(new_chat_members.toList()) left_chat_member != null -> LeftChatMemberEvent(left_chat_member) new_chat_title != null -> NewChatTitle(new_chat_title) - new_chat_photo != null -> NewChatPhoto(new_chat_photo.toList()) + new_chat_photo != null -> NewChatPhoto(new_chat_photo) video_chat_started != null -> video_chat_started video_chat_scheduled != null -> video_chat_scheduled message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt index 7290ebb58e..69a1906a3c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt @@ -1,19 +1,46 @@ package dev.inmo.tgbotapi.types.message.abstracts +import dev.inmo.tgbotapi.abstracts.WithMessageId import korlibs.time.DateTime import dev.inmo.tgbotapi.abstracts.WithPreviewChatAndMessageId +import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import dev.inmo.tgbotapi.types.MessageId +import dev.inmo.tgbotapi.types.MessageThreadId import dev.inmo.tgbotapi.types.chat.PreviewChat import dev.inmo.tgbotapi.types.message.RawMessage +import dev.inmo.tgbotapi.types.threadId import kotlinx.serialization.* import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import kotlin.jvm.JvmInline @ClassCastsIncluded(excludeRegex = ".*Impl") interface Message : WithPreviewChatAndMessageId { val date: DateTime + val metaInfo: MetaInfo + get() = MetaInfo(chat.id, messageId) + + @Serializable + @JvmInline + value class MetaInfo( + val chatIdMessageIdThreadId: Triple + ) : WithMessageId { + val chatId: ChatIdentifier + get() = chatIdMessageIdThreadId.first + override val messageId: MessageId + get() = chatIdMessageIdThreadId.second + val threadId: MessageThreadId? + get() = chatIdMessageIdThreadId.third + + constructor(chatId: ChatIdentifier, messageId: MessageId, threadId: MessageThreadId? = chatId.threadId) : this(Triple(chatId, messageId, threadId)) + constructor(chatIdMessageId: Pair, threadId: MessageThreadId? = chatIdMessageId.first.threadId) : this(Triple(chatIdMessageId.first, chatIdMessageId.second, threadId)) + + fun copy( + chatId: ChatIdentifier = this.chatId, messageId: MessageId = this.messageId, threadId: MessageThreadId? = chatId.threadId + ) = MetaInfo(chatId, messageId, threadId) + } } interface AccessibleMessage : Message diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt index 32e0299a2e..4f25de4ed1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt @@ -52,6 +52,8 @@ sealed interface MessageContent: ResendableContent { subclass(StickerContent::class) subclass(InvoiceContent::class) subclass(StoryContent::class) + subclass(GiveawayPublicResultsContent::class) + subclass(ScheduledGiveawayContent::class) additionalBuilder() } @@ -139,18 +141,6 @@ sealed interface TextedContent : MessageContent, TextedInput sealed interface MediaContent: MessageContent { val media: TelegramMediaFile fun asTelegramMedia(): TelegramMedia - - override fun createResend( - chatId: ChatIdentifier, - messageThreadId: MessageThreadId?, - disableNotification: Boolean, - protectContent: Boolean, - replyToMessageId: MessageId?, - allowSendingWithoutReply: Boolean?, - replyMarkup: KeyboardMarkup? - ): Request> { - TODO("Not yet implemented") - } } sealed interface SpoilerableMediaContent : MediaContent, SpoilerableData diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/GiveawayPublicResultsContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/GiveawayPublicResultsContent.kt index 3d4a5e4ded..29e9e0b348 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/GiveawayPublicResultsContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/GiveawayPublicResultsContent.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.types.message.content +import dev.inmo.tgbotapi.requests.ForwardMessage import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup @@ -20,6 +21,13 @@ data class GiveawayPublicResultsContent( allowSendingWithoutReply: Boolean?, replyMarkup: KeyboardMarkup? ): Request { - TODO("Not yet implemented") + return ForwardMessage( + giveaway.chat.id, + toChatId = chatId, + messageId = giveaway.messageId, + threadId = messageThreadId, + disableNotification = disableNotification, + protectContent = protectContent + ) } } \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/ScheduledGiveawayContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/ScheduledGiveawayContent.kt index 47386da9ef..f3b4125a44 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/ScheduledGiveawayContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/ScheduledGiveawayContent.kt @@ -1,9 +1,11 @@ package dev.inmo.tgbotapi.types.message.content import dev.inmo.micro_utils.language_codes.IetfLang +import dev.inmo.tgbotapi.requests.ForwardMessage import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup +import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.PreviewChat import dev.inmo.tgbotapi.types.giveaway.GiveawayInfo import dev.inmo.tgbotapi.types.giveaway.ScheduledGiveaway @@ -13,6 +15,8 @@ import kotlinx.serialization.Serializable @Serializable data class ScheduledGiveawayContent( + private val chat: Chat, + private val messageId: MessageId, val giveaway: ScheduledGiveaway ) : MessageContent { override fun createResend( @@ -24,6 +28,13 @@ data class ScheduledGiveawayContent( allowSendingWithoutReply: Boolean?, replyMarkup: KeyboardMarkup? ): Request { - TODO("Not yet implemented") + return ForwardMessage( + chat.id, + toChatId = chatId, + messageId = messageId, + threadId = messageThreadId, + disableNotification = disableNotification, + protectContent = protectContent + ) } } \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/Invoice.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/Invoice.kt index 03d3c10b64..cd10c9f0f1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/Invoice.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/Invoice.kt @@ -17,4 +17,4 @@ data class Invoice( override val currency: Currency, @SerialName(totalAmountField) override val amount: Long -) : Amounted, Currencied +) : Amounted, Currencied, ExternalReplyInfo.ContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt index bb07e64c16..183a65abdc 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt @@ -49,7 +49,7 @@ val LongSeconds.asExactScheduledCloseInfo @Serializable(PollSerializer::class) @ClassCastsIncluded -sealed interface Poll { +sealed interface Poll : ExternalReplyInfo.ContentVariant { val id: PollIdentifier val question: String val options: List diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/stories/Story.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/stories/Story.kt index 592188a196..c17452cf3a 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/stories/Story.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/stories/Story.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.types.stories +import dev.inmo.tgbotapi.types.ExternalReplyInfo import kotlinx.serialization.Serializable @Serializable -class Story +class Story : ExternalReplyInfo.ContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/venue/Venue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/venue/Venue.kt index f96a1f26bf..5dc5b71a3e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/venue/Venue.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/venue/Venue.kt @@ -23,4 +23,4 @@ data class Venue( override val googlePlaceId: GooglePlaceId? = null, @SerialName(googlePlaceTypeField) override val googlePlaceType: GooglePlaceType? = null -) : CommonVenueData, Locationed by location +) : CommonVenueData, Locationed by location, ExternalReplyInfo.ContentVariant