mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI-examples.git
synced 2026-10-16 00:50:20 +00:00
fix(rich-messages): update date formats and handle draft stops
Use typed date-time formats and a downloadable sample document. Wait five seconds between draft chunks so users can stop generation; match stop events to the originating chat and acknowledge them there.
This commit is contained in:
@@ -21,6 +21,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPhoto
|
|||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onRichMessage
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onRichMessage
|
||||||
import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull
|
import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull
|
||||||
import dev.inmo.tgbotapi.extensions.utils.contentMessageOrNull
|
import dev.inmo.tgbotapi.extensions.utils.contentMessageOrNull
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat
|
||||||
import dev.inmo.tgbotapi.extensions.utils.onlyRichMessageContentMessages
|
import dev.inmo.tgbotapi.extensions.utils.onlyRichMessageContentMessages
|
||||||
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
|
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
|
||||||
import dev.inmo.tgbotapi.requests.edit.text.EditChatMessageRichText
|
import dev.inmo.tgbotapi.requests.edit.text.EditChatMessageRichText
|
||||||
@@ -28,6 +29,7 @@ import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
|
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
|
||||||
import dev.inmo.tgbotapi.types.BotCommand
|
import dev.inmo.tgbotapi.types.BotCommand
|
||||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
import dev.inmo.tgbotapi.types.CustomEmojiId
|
||||||
|
import dev.inmo.tgbotapi.types.DateTimeEntityFormatting
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputRichMessageContent
|
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputRichMessageContent
|
||||||
import dev.inmo.tgbotapi.types.InlineQueryId
|
import dev.inmo.tgbotapi.types.InlineQueryId
|
||||||
@@ -56,6 +58,7 @@ import dev.inmo.tgbotapi.types.rich.RichTextPlain
|
|||||||
import dev.inmo.tgbotapi.types.rich.buildRichText
|
import dev.inmo.tgbotapi.types.rich.buildRichText
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CopyTextButtonData
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CopyTextButtonData
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryChosenChat
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.SwitchInlineQueryChosenChat
|
||||||
|
import dev.inmo.tgbotapi.types.directMessageThreadIdOrMessageThreadIdAsDirectMessageThreadId
|
||||||
import dev.inmo.tgbotapi.types.toChatId
|
import dev.inmo.tgbotapi.types.toChatId
|
||||||
import dev.inmo.tgbotapi.utils.DraftIdAllocator
|
import dev.inmo.tgbotapi.utils.DraftIdAllocator
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -353,7 +356,15 @@ suspend fun main(vararg args: String) {
|
|||||||
plain("\n")
|
plain("\n")
|
||||||
customEmoji(CustomEmojiId("5368324170671202286"), "👍")
|
customEmoji(CustomEmojiId("5368324170671202286"), "👍")
|
||||||
plain("\n")
|
plain("\n")
|
||||||
dateTime("22:45 tomorrow", TelegramDate(1647531900L), "wDT")
|
dateTime(
|
||||||
|
text = "22:45 tomorrow",
|
||||||
|
unixTime = TelegramDate(1647531900L),
|
||||||
|
dateTimeFormat = DateTimeEntityFormatting(
|
||||||
|
useWeek = true,
|
||||||
|
useDateLong = false,
|
||||||
|
useTimeLong = false
|
||||||
|
)
|
||||||
|
)
|
||||||
plain("\n")
|
plain("\n")
|
||||||
mathematicalExpression("x^2 + y^2")
|
mathematicalExpression("x^2 + y^2")
|
||||||
plain("\n#hashtag ${'$'}USD +12345678901, card: 4242 4242 4242 4242, https://t.me t.me a@t.me /command @username\n")
|
plain("\n#hashtag ${'$'}USD +12345678901, card: 4242 4242 4242 4242, https://t.me t.me a@t.me /command @username\n")
|
||||||
@@ -714,11 +725,12 @@ suspend fun main(vararg args: String) {
|
|||||||
// sendRichMessageDraft: stream partial rich messages sharing one draftId, then finalize
|
// sendRichMessageDraft: stream partial rich messages sharing one draftId, then finalize
|
||||||
// with a full sendRichMessage. Emulates streaming of an AI-generated reply.
|
// with a full sendRichMessage. Emulates streaming of an AI-generated reply.
|
||||||
onCommand("rich_draft", initialFilter = { it.chat is PrivateChat }) { origin ->
|
onCommand("rich_draft", initialFilter = { it.chat is PrivateChat }) { origin ->
|
||||||
val chatId = origin.chat.id.toChatId()
|
|
||||||
val draftId = richDraftIds.allocate()
|
val draftId = richDraftIds.allocate()
|
||||||
val stoppedUpdate = async(start = CoroutineStart.UNDISPATCHED) {
|
val stoppedUpdate = async(start = CoroutineStart.UNDISPATCHED) {
|
||||||
waitMessageGenerationStopped()
|
waitMessageGenerationStopped()
|
||||||
.filter { it.chat.id == origin.chat.id && it.draftId == draftId }
|
.filter {
|
||||||
|
it.sameChat(origin) && it.draftId == draftId
|
||||||
|
}
|
||||||
.first()
|
.first()
|
||||||
}
|
}
|
||||||
val parts = listOf(
|
val parts = listOf(
|
||||||
@@ -729,20 +741,20 @@ suspend fun main(vararg args: String) {
|
|||||||
try {
|
try {
|
||||||
parts.forEach { part ->
|
parts.forEach { part ->
|
||||||
sendRichMessageDraft(
|
sendRichMessageDraft(
|
||||||
chatId,
|
origin.chat.id,
|
||||||
draftId.long,
|
draftId.long,
|
||||||
InputRichMessageMarkdown(part),
|
InputRichMessageMarkdown(part),
|
||||||
canStop = true,
|
canStop = true,
|
||||||
keepOnStop = true,
|
keepOnStop = true,
|
||||||
)
|
)
|
||||||
val stopped = withTimeoutOrNull(1000L) { stoppedUpdate.await() }
|
val stopped = withTimeoutOrNull(5000L) { stoppedUpdate.await() }
|
||||||
if (stopped != null) {
|
if (stopped != null) {
|
||||||
println("Stopped rich draft ${stopped.draftId.long} in ${stopped.chat.id}")
|
reply(origin, "Stopped rich draft ${stopped.draftId.long} in ${stopped.chat.id}")
|
||||||
return@onCommand
|
return@onCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finalize only if the user did not stop generation; a normal message removes a retained draft.
|
// Finalize only if the user did not stop generation; a normal message removes a retained draft.
|
||||||
sendRichMessage(chatId, InputRichMessageMarkdown("Done! Here is the *final* rich message."))
|
sendRichMessage(origin.chat.id, InputRichMessageMarkdown("Done! Here is the *final* rich message."))
|
||||||
} finally {
|
} finally {
|
||||||
stoppedUpdate.cancel()
|
stoppedUpdate.cancel()
|
||||||
richDraftIds.free(draftId)
|
richDraftIds.free(draftId)
|
||||||
@@ -837,7 +849,7 @@ suspend fun main(vararg args: String) {
|
|||||||
|
|
||||||
expandableBlockQuotation(credit = RichTextPlain("Expandable quotation credit")) {
|
expandableBlockQuotation(credit = RichTextPlain("Expandable quotation credit")) {
|
||||||
plain("This quotation starts collapsed and can be expanded by the reader. ")
|
plain("This quotation starts collapsed and can be expanded by the reader. ")
|
||||||
dateTime("Bot API 10.3", TelegramDate(1787518800L), "d MMMM yyyy")
|
dateTime("Bot API 10.3", TelegramDate(1787518800L), DateTimeEntityFormatting(useDateLong = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
table(
|
table(
|
||||||
@@ -904,7 +916,7 @@ suspend fun main(vararg args: String) {
|
|||||||
|
|
||||||
document(
|
document(
|
||||||
TelegramMediaDocument(
|
TelegramMediaDocument(
|
||||||
InputFile.fromUrl("https://telegram.org/example/document.pdf")
|
InputFile.fromUrl("https://github.com/InsanusMokrassar/ktgbotapi/archive/refs/heads/master.zip"),
|
||||||
),
|
),
|
||||||
RichBlockCaption(RichTextPlain("A general-file document block")),
|
RichBlockCaption(RichTextPlain("A general-file document block")),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user