From 3ca3e571b5686c9e9e170fbba2089518392a8040 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 1 Sep 2026 19:14:29 +0600 Subject: [PATCH] feat(api)!: widen rich draft chat identifier BREAKING CHANGE: SendRichMessageDraft, sendRichMessageDraft, and the rich-draft send overload now accept IdChatIdentifier. Existing ChatId source calls remain valid; JVM signatures changed. --- CHANGELOG.md | 3 + tgbotapi.api/api/tgbotapi.api.api | 8 +- .../api/send/SendRichMessageDraft.kt | 7 +- .../tgbotapi/extensions/api/send/Sends.kt | 3 +- .../api/send/SendRichMessageDraftTest.kt | 76 +++++++++++++++++++ tgbotapi.core/api/tgbotapi.core.api | 12 +-- .../requests/send/SendRichMessageDraft.kt | 5 +- .../tgbotapi/types/GeneralBotApi103Test.kt | 12 +++ 8 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 tgbotapi.api/src/commonTest/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraftTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac0fb3840..99ab037307 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * `ChatAdministratorRights` gained the abstract `canSendWelcomeMessages` property; implementations maintained in the same compilation module must supply the property, while `ChatCommonAdministratorRights` construction can use the new trailing default * `FlowsUpdatesFilter` gained the abstract `messageGenerationStoppedUpdatesFlow` property; direct implementations must supply the flow, while subclasses of `AbstractFlowsUpdatesFilter` inherit the filtered implementation * `RichText` gained the public `isValidRichMessageButtonText` contract and the `RichText`/`RichBlock`/`InputRichBlock` sealed hierarchies gained Bot API 10.3 variants; permitted same-module implementations and exhaustive `when` expressions must cover the new contracts and variants +* `SendRichMessageDraft`, `sendRichMessageDraft`, and the corresponding generic `send` overload widened `chatId` from `ChatId` to `IdChatIdentifier`; source calls passing `ChatId` remain valid, while the JVM signatures changed **Migration advice**: Direct and generic `send` extensions accept either `receiverUserId = userId, callbackQueryId = callbackId, replaceCallbackQueryMessage = ...` or `ephemeralMessageParameters = EphemeralMessageParameters(receiverUserId = userId, callbackQueryId = callbackId, replaceCallbackQueryMessage = ...)`; send-request constructors and `reply` API overloads require the parameter-object form; add `canSendWelcomeMessages` and `messageGenerationStoppedUpdatesFlow` to direct interface implementations; add Bot API 10.3 branches to exhaustive rich-type `when` expressions @@ -17,6 +18,7 @@ * `Core`: * (`Ephemeral messages`) Added `EphemeralMessageParameters`; replaced the flat send-request recipient/callback parameters with `ephemeralMessageParameters`, including callback-message replacement support + * (`Rich Messages`) Widened `SendRichMessageDraft.chatId` from `ChatId` to `IdChatIdentifier`, allowing thread-bearing numeric identifiers to supply the default message thread * (`Ephemeral messages`) Added new-file uploads for `editEphemeralMessageMedia`; collected secondary live-photo `photo` attachments for ephemeral and regular media edits, media groups, and paid media; added `showCaptionAboveMedia` for caption edits and rich-message text edits * (`Ephemeral messages`) Added `canSendWelcomeMessages` administrator right and `promoteChatMember` parameter * (`Rich Messages`) Added rich-message button actions, rich-text/button-row entities, typed button styles/alignment, expandable block quotations, compact tables, document blocks, document media links and direct document uploads @@ -30,6 +32,7 @@ * (`General`) Added legacy and generated class casts for `MessageGenerationStoppedUpdate` * `API`: * (`Ephemeral messages`) Migrated send/reply extension surfaces to `ephemeralMessageParameters`; added rich ephemeral text editing and caption-above-media support + * (`Rich Messages`) Widened `sendRichMessageDraft` and the corresponding generic `send` overload from `ChatId` to `IdChatIdentifier` * (`Ephemeral messages`) Retained 172 non-deprecated direct and generic `send` overloads accepting `receiverUserId`/`callbackQueryId`/`replaceCallbackQueryMessage` as an alternative API form; every overload delegates to the corresponding `ephemeralMessageParameters` overload * (`Ephemeral messages`) Added named rich-message overloads and generic `InputRichMessage`/`RichMessageContent` aliases across both ephemeral reply families * (`General`) Added `canStop`/`keepOnStop` to `sendMessageDraft`/`sendRichMessageDraft` extension surfaces, including streaming draft flows and `send` overloads diff --git a/tgbotapi.api/api/tgbotapi.api.api b/tgbotapi.api/api/tgbotapi.api.api index 6c32284d3a..da157d2055 100644 --- a/tgbotapi.api/api/tgbotapi.api.api +++ b/tgbotapi.api/api/tgbotapi.api.api @@ -2263,8 +2263,8 @@ public final class dev/inmo/tgbotapi/extensions/api/send/SendMessageKt { } public final class dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraftKt { - public static final fun sendRichMessageDraft-51n8fGs (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun sendRichMessageDraft-51n8fGs$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static final fun sendRichMessageDraft-ISPvrcY (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun sendRichMessageDraft-ISPvrcY$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class dev/inmo/tgbotapi/extensions/api/send/SendRichMessageKt { @@ -2347,8 +2347,6 @@ public final class dev/inmo/tgbotapi/extensions/api/send/SendsKt { public static final fun send-43MdJKs (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;JLjava/lang/String;Ldev/inmo/tgbotapi/types/message/ParseMode;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun send-43MdJKs$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLjava/lang/String;Ldev/inmo/tgbotapi/types/message/ParseMode;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun send-43MdJKs$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;JLjava/lang/String;Ldev/inmo/tgbotapi/types/message/ParseMode;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun send-51n8fGs (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun send-51n8fGs$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static final fun send-59dkE5s (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;DDLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;Ldev/inmo/tgbotapi/types/EphemeralMessageParameters;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun send-59dkE5s (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ldev/inmo/tgbotapi/types/files/AnimationFile;Ljava/lang/String;Ldev/inmo/tgbotapi/types/message/ParseMode;ZZLjava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;Ldev/inmo/tgbotapi/types/EphemeralMessageParameters;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun send-59dkE5s (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;DDLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;Ldev/inmo/tgbotapi/types/EphemeralMessageParameters;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2381,6 +2379,8 @@ public final class dev/inmo/tgbotapi/extensions/api/send/SendsKt { public static synthetic fun send-BKdLCOc$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZZLdev/inmo/tgbotapi/types/polls/ScheduledCloseInfo;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static final fun send-I3_Lavo (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/Integer;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;ZZZZZZZLdev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/InlineKeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun send-I3_Lavo$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/Integer;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;ZZZZZZZLdev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/InlineKeyboardMarkup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static final fun send-ISPvrcY (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun send-ISPvrcY$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static final fun send-JGcy_pA (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ldev/inmo/tgbotapi/types/polls/RegularPoll;Ljava/util/List;ZLjava/util/List;ZZLdev/inmo/tgbotapi/types/polls/ScheduledCloseInfo;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun send-JGcy_pA (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ljava/lang/String;Ljava/util/List;Ldev/inmo/tgbotapi/types/message/ParseMode;ZZZLdev/inmo/tgbotapi/types/polls/ScheduledCloseInfo;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun send-JGcy_pA (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;Ldev/inmo/tgbotapi/types/polls/RegularPoll;Ljava/util/List;ZLjava/util/List;ZZLdev/inmo/tgbotapi/types/polls/ScheduledCloseInfo;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraft.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraft.kt index f3c84012a0..a75aa897f2 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraft.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraft.kt @@ -2,12 +2,15 @@ package dev.inmo.tgbotapi.extensions.api.send import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.send.SendRichMessageDraft -import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.types.IdChatIdentifier import dev.inmo.tgbotapi.types.MessageThreadId import dev.inmo.tgbotapi.types.rich.InputRichMessage +/** + * @param chatId Numeric target chat identifier. Identifiers carrying a thread supply the default [threadId]. + */ public suspend fun TelegramBot.sendRichMessageDraft( - chatId: ChatId, + chatId: IdChatIdentifier, draftId: Long, richMessage: InputRichMessage, threadId: MessageThreadId? = chatId.threadId, diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/Sends.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/Sends.kt index 8b3c1bddc5..b0c7d83dd5 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/Sends.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/Sends.kt @@ -2602,9 +2602,10 @@ public suspend fun TelegramBot.send( /** * Will execute [sendRichMessageDraft] request + * @param chatId Numeric target chat identifier. Identifiers carrying a thread supply the default [threadId]. */ public suspend fun TelegramBot.send( - chatId: ChatId, + chatId: IdChatIdentifier, draftId: Long, richMessage: InputRichMessage, threadId: MessageThreadId? = chatId.threadId, diff --git a/tgbotapi.api/src/commonTest/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraftTest.kt b/tgbotapi.api/src/commonTest/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraftTest.kt new file mode 100644 index 0000000000..71eba3c201 --- /dev/null +++ b/tgbotapi.api/src/commonTest/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraftTest.kt @@ -0,0 +1,76 @@ +package dev.inmo.tgbotapi.extensions.api.send + +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.requests.send.SendRichMessageDraft +import dev.inmo.tgbotapi.types.ChatIdWithThreadId +import dev.inmo.tgbotapi.types.IdChatIdentifier +import dev.inmo.tgbotapi.types.MessageThreadId +import dev.inmo.tgbotapi.types.RawChatId +import dev.inmo.tgbotapi.types.rich.InputRichMessageHTML +import kotlin.coroutines.Continuation +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.coroutines.startCoroutine +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs +import kotlin.test.assertSame + +class SendRichMessageDraftTest { + private object RequestCaptured : Throwable() + + private class CapturingBot : RequestsExecutor { + lateinit var request: Request<*> + + override suspend fun execute(request: Request): T { + this.request = request + throw RequestCaptured + } + + override fun close() = Unit + } + + private fun CapturingBot.capture(block: suspend CapturingBot.() -> Unit): Request<*> { + var completion: Result? = null + block.startCoroutine( + this, + object : Continuation { + override val context = EmptyCoroutineContext + + override fun resumeWith(result: Result) { + completion = result + } + } + ) + + val completed = completion ?: error("Request coroutine did not complete synchronously") + assertSame(RequestCaptured, completed.exceptionOrNull()) + return request + } + + @Test + fun directExtensionAcceptsIdChatIdentifier() { + val chatId: IdChatIdentifier = ChatIdWithThreadId(RawChatId(1L), MessageThreadId(2L)) + val request = assertIs( + CapturingBot().capture { + sendRichMessageDraft(chatId, 3L, InputRichMessageHTML("direct")) + } + ) + + assertEquals(chatId, request.chatId) + assertEquals(MessageThreadId(2L), request.threadId) + } + + @Test + fun genericExtensionAcceptsIdChatIdentifier() { + val chatId: IdChatIdentifier = ChatIdWithThreadId(RawChatId(4L), MessageThreadId(5L)) + val request = assertIs( + CapturingBot().capture { + send(chatId, 6L, InputRichMessageHTML("generic")) + } + ) + + assertEquals(chatId, request.chatId) + assertEquals(MessageThreadId(5L), request.threadId) + } +} diff --git a/tgbotapi.core/api/tgbotapi.core.api b/tgbotapi.core/api/tgbotapi.core.api index 6a6129f7f0..c04bc657d6 100644 --- a/tgbotapi.core/api/tgbotapi.core.api +++ b/tgbotapi.core/api/tgbotapi.core.api @@ -7070,19 +7070,19 @@ public final class dev/inmo/tgbotapi/requests/send/SendRichMessage$Companion { public final class dev/inmo/tgbotapi/requests/send/SendRichMessageDraft : dev/inmo/tgbotapi/requests/abstracts/SimpleRequest { public static final field Companion Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft$Companion; - public synthetic fun (JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun (JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1-tHkBKVM ()J + public synthetic fun (Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ldev/inmo/tgbotapi/types/IdChatIdentifier; public final fun component2 ()J public final fun component3 ()Ldev/inmo/tgbotapi/types/rich/InputRichMessage; public final fun component4-S3HF-10 ()Ldev/inmo/tgbotapi/types/MessageThreadId; public final fun component5 ()Ljava/lang/Boolean; public final fun component6 ()Ljava/lang/Boolean; - public final fun copy-Nl5m_rE (JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft; - public static synthetic fun copy-Nl5m_rE$default (Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft; + public final fun copy-GAvqYPo (Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft; + public static synthetic fun copy-GAvqYPo$default (Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft;Ldev/inmo/tgbotapi/types/IdChatIdentifier;JLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Ldev/inmo/tgbotapi/requests/send/SendRichMessageDraft; public fun equals (Ljava/lang/Object;)Z public final fun getCanStop ()Ljava/lang/Boolean; - public final fun getChatId-tHkBKVM ()J + public final fun getChatId ()Ldev/inmo/tgbotapi/types/IdChatIdentifier; public final fun getDraftId ()J public final fun getKeepOnStop ()Ljava/lang/Boolean; public fun getRequestSerializer ()Lkotlinx/serialization/SerializationStrategy; diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendRichMessageDraft.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendRichMessageDraft.kt index aa9ea4db17..c71f9de950 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendRichMessageDraft.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendRichMessageDraft.kt @@ -1,7 +1,7 @@ package dev.inmo.tgbotapi.requests.send import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest -import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.types.IdChatIdentifier import dev.inmo.tgbotapi.types.MessageThreadId import dev.inmo.tgbotapi.types.canStopField import dev.inmo.tgbotapi.types.chatIdField @@ -22,12 +22,13 @@ import kotlinx.serialization.SerializationStrategy * ephemeral and acts as a temporary 30-second preview - once the output is finalized, [SendRichMessage] must be called * with the complete message to persist it in the user's chat. * + * @param chatId Numeric target chat identifier. Identifiers carrying a thread supply the default [threadId]. * @see sendRichMessageDraft */ @Serializable data class SendRichMessageDraft( @SerialName(chatIdField) - val chatId: ChatId, + val chatId: IdChatIdentifier, /** * Unique identifier of the message draft; must be non-zero. Changes to drafts with the same identifier are animated. */ diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/GeneralBotApi103Test.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/GeneralBotApi103Test.kt index 2a2adf843a..14554ff4a2 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/GeneralBotApi103Test.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/GeneralBotApi103Test.kt @@ -37,6 +37,18 @@ class GeneralBotApi103Test { assertEquals("true", richDraftJson[keepOnStopField].toString()) } + @Test + fun `rich draft accepts thread-bearing chat identifiers`() { + val chatId = ChatIdWithThreadId(RawChatId(3L), MessageThreadId(4L)) + val richDraft = SendRichMessageDraft(chatId, 5L, InputRichMessageHTML("draft")) + val richDraftJson = json.encodeToJsonElement(SendRichMessageDraft.serializer(), richDraft).jsonObject + + assertEquals(chatId, richDraft.chatId) + assertEquals(MessageThreadId(4L), richDraft.threadId) + assertEquals("3", richDraftJson[chatIdField].toString()) + assertEquals("4", richDraftJson[messageThreadIdField].toString()) + } + @Test fun `stopped message generation update deserializes`() { val update = nonstrictJsonFormat.decodeFromString(