mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI-examples.git
synced 2026-09-13 11:34:13 +00:00
187 lines
9.0 KiB
Kotlin
187 lines
9.0 KiB
Kotlin
import dev.inmo.kslog.common.KSLog
|
|
import dev.inmo.kslog.common.LogLevel
|
|
import dev.inmo.kslog.common.defaultMessageFormatter
|
|
import dev.inmo.kslog.common.setDefaultKSLog
|
|
import dev.inmo.micro_utils.coroutines.subscribeLoggingDropExceptions
|
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
|
import dev.inmo.tgbotapi.extensions.api.edit.media.editMessageMedia
|
|
import dev.inmo.tgbotapi.extensions.api.send.media.sendLivePhoto
|
|
import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup
|
|
import dev.inmo.tgbotapi.extensions.api.send.media.sendPaidMedia
|
|
import dev.inmo.tgbotapi.extensions.api.send.reply
|
|
import dev.inmo.tgbotapi.extensions.api.send.replyWithLivePhoto
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onEditedLivePhoto
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onLivePhoto
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onLivePhotoGallery
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMediaGroupMessages
|
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPaidMediaInfoContent
|
|
import dev.inmo.tgbotapi.extensions.utils.contentMessageOrNull
|
|
import dev.inmo.tgbotapi.extensions.utils.photoContentOrNull
|
|
import dev.inmo.tgbotapi.extensions.utils.photoFileOrNull
|
|
import dev.inmo.tgbotapi.extensions.utils.videoContentOrNull
|
|
import dev.inmo.tgbotapi.extensions.utils.videoFileOrNull
|
|
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
|
|
import dev.inmo.tgbotapi.types.message.content.LivePhotoContent
|
|
import dev.inmo.tgbotapi.types.message.payments.PaidMedia
|
|
import dev.inmo.tgbotapi.types.media.TelegramMediaLivePhoto
|
|
import dev.inmo.tgbotapi.types.media.TelegramPaidMediaLivePhoto
|
|
import dev.inmo.tgbotapi.types.media.toTelegramPaidMediaLivePhoto
|
|
import dev.inmo.tgbotapi.types.message.content.MediaContent
|
|
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
|
|
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
|
|
import dev.inmo.tgbotapi.types.message.content.VideoContent
|
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
/**
|
|
* Starts the long-polling example for receiving, sending, grouping, editing, and selling Live Photos.
|
|
*
|
|
* @param args bot token followed by the optional, case-sensitive `debug` and `testServer` flags; unknown trailing
|
|
* arguments are ignored
|
|
*/
|
|
@OptIn(RiskFeature::class)
|
|
suspend fun main(vararg args: String) {
|
|
val botToken = args.first()
|
|
val isDebug = args.any { it == "debug" }
|
|
val isTestServer = args.any { it == "testServer" }
|
|
|
|
if (isDebug) {
|
|
setDefaultKSLog(
|
|
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
|
|
println(defaultMessageFormatter(level, tag, message, throwable))
|
|
}
|
|
)
|
|
}
|
|
|
|
telegramBotWithBehaviourAndLongPolling(
|
|
botToken,
|
|
CoroutineScope(Dispatchers.IO),
|
|
testServer = isTestServer
|
|
) {
|
|
|
|
// Demonstrates: LivePhoto class (LivePhotoFile), live_photo field in Message, sendLivePhoto,
|
|
// InputMediaLivePhoto (TelegramMediaLivePhoto), InputPaidMediaLivePhoto (TelegramPaidMediaLivePhoto),
|
|
// editMessageMedia with live photo
|
|
onLivePhoto { message ->
|
|
// message.content is LivePhotoContent — this is the live_photo field of Message
|
|
val content: LivePhotoContent = message.content
|
|
|
|
// content.media is LivePhotoFile — the LivePhoto class (photo + short video in one file)
|
|
val livePhotoFile = content.media
|
|
println("=== Live photo received ===")
|
|
println(" fileId: ${livePhotoFile.fileId}")
|
|
println(" fileUniqueId: ${livePhotoFile.fileUniqueId}")
|
|
println(" width: ${livePhotoFile.width}")
|
|
println(" height: ${livePhotoFile.height}")
|
|
println(" duration: ${livePhotoFile.duration}s")
|
|
println(" photo (thumb): ${livePhotoFile.photo?.fileId}")
|
|
println(" mimeType: ${livePhotoFile.mimeType}")
|
|
println(" fileSize: ${livePhotoFile.fileSize}")
|
|
println(" caption: ${content.text}")
|
|
|
|
// sendLivePhoto: resend the received live photo back using LivePhotoFile overload
|
|
val sent = sendLivePhoto(
|
|
chatId = message.chat.id,
|
|
livePhoto = livePhotoFile,
|
|
text = "Resent via sendLivePhoto"
|
|
)
|
|
println(" sent message id: ${sent.messageId}")
|
|
|
|
// InputPaidMediaLivePhoto (TelegramPaidMediaLivePhoto): send the live photo as paid media (1 star)
|
|
sendPaidMedia(
|
|
chatId = message.chat.id,
|
|
starCount = 1,
|
|
media = listOf(
|
|
// TelegramPaidMediaLivePhoto is InputPaidMediaLivePhoto
|
|
TelegramPaidMediaLivePhoto(
|
|
file = livePhotoFile.fileId,
|
|
photo = livePhotoFile.photo?.fileId ?: livePhotoFile.fileId
|
|
)
|
|
),
|
|
text = "Paid live photo (1 star)"
|
|
)
|
|
|
|
// editMessageMedia with InputMediaLivePhoto (TelegramMediaLivePhoto):
|
|
// edit the previously sent message to replace it with itself via TelegramMediaLivePhoto
|
|
val sentAsMedia = sent.withContentOrNull<LivePhotoContent>()
|
|
if (sentAsMedia != null) {
|
|
editMessageMedia(
|
|
message = sentAsMedia,
|
|
// TelegramMediaLivePhoto is InputMediaLivePhoto
|
|
media = TelegramMediaLivePhoto(
|
|
file = livePhotoFile.fileId,
|
|
photo = livePhotoFile.photo?.fileId ?: livePhotoFile.fileId,
|
|
text = "Edited via editMessageMedia with TelegramMediaLivePhoto"
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
// Demonstrates: sendMediaGroup with live photos, InputMediaLivePhoto (TelegramMediaLivePhoto)
|
|
onLivePhotoGallery { mediaGroupContent ->
|
|
println("=== Live photo gallery received (${mediaGroupContent.group.size} items) ===")
|
|
mediaGroupContent.group.forEach { groupMember ->
|
|
val livePhotoFile = groupMember.content.media
|
|
println(" - fileId: ${livePhotoFile.fileId}, ${livePhotoFile.width}x${livePhotoFile.height}")
|
|
}
|
|
|
|
// sendMediaGroup with TelegramMediaLivePhoto (InputMediaLivePhoto)
|
|
sendMediaGroup(
|
|
chatId = mediaGroupContent.group.first().sourceMessage.chat.id,
|
|
media = mediaGroupContent.group.map { groupMember ->
|
|
val livePhotoFile = groupMember.content.media
|
|
// TelegramMediaLivePhoto is InputMediaLivePhoto — used here in sendMediaGroup
|
|
TelegramMediaLivePhoto(
|
|
file = livePhotoFile.fileId,
|
|
photo = livePhotoFile.photo?.fileId ?: livePhotoFile.fileId
|
|
)
|
|
}
|
|
)
|
|
}
|
|
|
|
// Demonstrates: PaidMediaLivePhoto (PaidMedia.LivePhoto) in received paid media content
|
|
onPaidMediaInfoContent { message ->
|
|
val paidMedia = message.content.paidMediaInfo.media
|
|
val livePhotos = paidMedia.filterIsInstance<PaidMedia.LivePhoto>()
|
|
if (livePhotos.isNotEmpty()) {
|
|
println("=== Paid media with live photos received ===")
|
|
livePhotos.forEach { paidLivePhoto ->
|
|
// paidLivePhoto is PaidMedia.LivePhoto — PaidMediaLivePhoto class
|
|
val livePhotoFile = paidLivePhoto.livePhoto
|
|
println(" - fileId: ${livePhotoFile.fileId}, ${livePhotoFile.width}x${livePhotoFile.height}")
|
|
println(" duration: ${livePhotoFile.duration}s")
|
|
}
|
|
reply(message, "Received ${livePhotos.size} paid live photo(s)")
|
|
}
|
|
}
|
|
|
|
// Demonstrates: live_photo field in edited messages (EditedMessage with LivePhotoContent)
|
|
onEditedLivePhoto { message ->
|
|
println("=== Edited live photo received ===")
|
|
println(" fileId: ${message.content.media.fileId}")
|
|
println(" caption: ${message.content.text}")
|
|
}
|
|
|
|
onMediaGroupMessages {
|
|
val photo = it.content.group.firstNotNullOfOrNull {
|
|
it.content.photoContentOrNull()
|
|
} ?: return@onMediaGroupMessages
|
|
val video = it.content.group.firstNotNullOfOrNull {
|
|
it.content.videoContentOrNull()
|
|
} ?: return@onMediaGroupMessages
|
|
replyWithLivePhoto(
|
|
it,
|
|
video.media.fileId,
|
|
photo.media.fileId
|
|
)
|
|
}
|
|
|
|
allUpdatesFlow.subscribeLoggingDropExceptions(scope = this) {
|
|
println(it)
|
|
}
|
|
}.second.join()
|
|
}
|