diff --git a/FilesLoaderBot/src/main/kotlin/FilesLoaderBot.kt b/FilesLoaderBot/src/main/kotlin/FilesLoaderBot.kt index 58dbd1a..f477391 100644 --- a/FilesLoaderBot/src/main/kotlin/FilesLoaderBot.kt +++ b/FilesLoaderBot/src/main/kotlin/FilesLoaderBot.kt @@ -1,10 +1,39 @@ +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.tgbotapi.extensions.api.files.downloadFile +import dev.inmo.tgbotapi.extensions.api.files.downloadFileToTemp import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.api.send.replyWithAnimation +import dev.inmo.tgbotapi.extensions.api.send.replyWithAudio +import dev.inmo.tgbotapi.extensions.api.send.replyWithDocument +import dev.inmo.tgbotapi.extensions.api.send.replyWithMediaGroup +import dev.inmo.tgbotapi.extensions.api.send.replyWithPhoto +import dev.inmo.tgbotapi.extensions.api.send.replyWithSticker +import dev.inmo.tgbotapi.extensions.api.send.replyWithVideo +import dev.inmo.tgbotapi.extensions.api.send.replyWithVideoNote +import dev.inmo.tgbotapi.extensions.api.send.replyWithVoice +import dev.inmo.tgbotapi.extensions.api.send.withAction 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.onContentMessage import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMedia +import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile +import dev.inmo.tgbotapi.requests.send.SendAction +import dev.inmo.tgbotapi.types.actions.BotAction +import dev.inmo.tgbotapi.types.actions.TypingAction +import dev.inmo.tgbotapi.types.media.TelegramMediaAudio +import dev.inmo.tgbotapi.types.media.TelegramMediaDocument +import dev.inmo.tgbotapi.types.media.TelegramMediaPhoto +import dev.inmo.tgbotapi.types.media.TelegramMediaVideo +import dev.inmo.tgbotapi.types.message.content.AnimationContent +import dev.inmo.tgbotapi.types.message.content.AudioContent +import dev.inmo.tgbotapi.types.message.content.DocumentContent +import dev.inmo.tgbotapi.types.message.content.MediaGroupContent +import dev.inmo.tgbotapi.types.message.content.PhotoContent +import dev.inmo.tgbotapi.types.message.content.StickerContent +import dev.inmo.tgbotapi.types.message.content.VideoContent +import dev.inmo.tgbotapi.types.message.content.VideoNoteContent +import dev.inmo.tgbotapi.types.message.content.VoiceContent import dev.inmo.tgbotapi.utils.filenameFromUrl import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -23,15 +52,72 @@ suspend fun main(args: Array) { reply(it, "Send me any media (like photo or video) to download it") } onMedia(initialFilter = null) { - val pathedFile = bot.getFileAdditionalInfo(it.content.media) + val content = it.content + val pathedFile = bot.getFileAdditionalInfo(content.media) val outFile = File(directoryOrFile, pathedFile.filePath.filenameFromUrl) runCatching { - bot.downloadFile(it.content.media, outFile) + bot.downloadFile(content.media, outFile) }.onFailure { it.printStackTrace() + }.onSuccess { _ -> + reply(it, "Saved to ${outFile.absolutePath}") + withAction(it.chat.id, TypingAction) { + when (content) { + is PhotoContent -> replyWithPhoto( + it, + outFile.asMultipartFile() + ) + is AnimationContent -> replyWithAnimation( + it, + outFile.asMultipartFile() + ) + is VideoContent -> replyWithVideo( + it, + outFile.asMultipartFile() + ) + is StickerContent -> replyWithSticker( + it, + outFile.asMultipartFile() + ) + is MediaGroupContent<*> -> replyWithMediaGroup( + it, + content.group.map { + when (val innerContent = it.content) { + is AudioContent -> TelegramMediaAudio( + downloadFileToTemp(innerContent.media).asMultipartFile() + ) + is DocumentContent -> TelegramMediaDocument( + downloadFileToTemp(innerContent.media).asMultipartFile() + ) + is PhotoContent -> TelegramMediaPhoto( + downloadFileToTemp(innerContent.media).asMultipartFile() + ) + is VideoContent -> TelegramMediaVideo( + downloadFileToTemp(innerContent.media).asMultipartFile() + ) + } + } + ) + is AudioContent -> replyWithAudio( + it, + outFile.asMultipartFile() + ) + is DocumentContent -> replyWithDocument( + it, + outFile.asMultipartFile() + ) + is VoiceContent -> replyWithVoice( + it, + outFile.asMultipartFile() + ) + is VideoNoteContent -> replyWithVideoNote( + it, + outFile.asMultipartFile() + ) + } + } } - reply(it, "Saved to ${outFile.absolutePath}") } - onContentMessage { println(it) } + allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) } }.second.join() } diff --git a/StickerSetHandler/README.md b/StickerSetHandler/README.md new file mode 100644 index 0000000..6849019 --- /dev/null +++ b/StickerSetHandler/README.md @@ -0,0 +1,9 @@ +# StickerSetHandler + +Send sticker to this bot to form your own stickers set. Send /delete to delete this sticker set + +## How to run + +```bash +./gradlew run --args="TOKEN" +``` diff --git a/StickerSetHandler/src/main/kotlin/StickerSetHandlerBot.kt b/StickerSetHandler/src/main/kotlin/StickerSetHandlerBot.kt index 1ed11d4..95b6330 100644 --- a/StickerSetHandler/src/main/kotlin/StickerSetHandlerBot.kt +++ b/StickerSetHandler/src/main/kotlin/StickerSetHandlerBot.kt @@ -3,46 +3,99 @@ import dev.inmo.tgbotapi.extensions.api.bot.getMe import dev.inmo.tgbotapi.extensions.api.files.downloadFile import dev.inmo.tgbotapi.extensions.api.files.downloadFileToTemp import dev.inmo.tgbotapi.extensions.api.get.getStickerSet +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.api.stickers.addStickerToSet import dev.inmo.tgbotapi.extensions.api.stickers.createNewStickerSet +import dev.inmo.tgbotapi.extensions.api.stickers.deleteStickerSet 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.onSticker import dev.inmo.tgbotapi.extensions.utils.extensions.raw.sticker import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile import dev.inmo.tgbotapi.requests.stickers.InputSticker +import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.files.* import dev.inmo.tgbotapi.types.toChatId +import dev.inmo.tgbotapi.utils.botCommand import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +/** + * Send sticker to this bot to form your own stickers set. Send /delete to delete this sticker set + */ suspend fun main(args: Array) { - telegramBotWithBehaviourAndLongPolling(args.first(), scope = CoroutineScope(Dispatchers.IO)) { + telegramBotWithBehaviourAndLongPolling( + args.first(), + scope = CoroutineScope(Dispatchers.IO), + defaultExceptionsHandler = { + it.printStackTrace() + } + ) { val me = getMe() + fun Chat.stickerSetName() = "s${id.chatId}_by_${me.username.usernameWithoutAt}" + onCommand("start") { + reply(it) { + botCommand("delete") + " - to clear stickers" + } + } + onCommand("delete") { + val deleted = runCatchingSafely { + deleteStickerSet(it.chat.stickerSetName()) + }.getOrElse { false } + + if (deleted) { + reply(it, "Deleted") + } else { + reply(it, "Can't delete for some of reason") + } + } onSticker { - val stickerSetName = "${it.chat.id}_by_${me.username.username}" + val stickerSetName = it.chat.stickerSetName() val sticker = it.content.media + val newSticker = when (sticker) { + is CustomEmojiSticker -> InputSticker.WithKeywords.CustomEmoji( + downloadFileToTemp(sticker.fileId).asMultipartFile(), + listOf(sticker.emoji ?: "\uD83D\uDE0A"), + emptyList() + ) + is MaskSticker -> InputSticker.Mask( + downloadFileToTemp(sticker.fileId).asMultipartFile(), + listOf(sticker.emoji ?: "\uD83D\uDE0A"), + sticker.maskPosition + ) + is RegularSticker -> InputSticker.WithKeywords.Regular( + downloadFileToTemp(sticker.fileId).asMultipartFile(), + listOf(sticker.emoji ?: "\uD83D\uDE0A"), + emptyList() + ) + is UnknownSticker -> return@onSticker + } runCatchingSafely { getStickerSet(stickerSetName) - }.getOrElse { _ -> + }.onSuccess { stickerSet -> + addStickerToSet(it.chat.id.toChatId(), stickerSet.name, newSticker).also { _ -> + reply( + it, + getStickerSet(stickerSetName).stickers.last() + ) + } + }.onFailure { _ -> createNewStickerSet( it.chat.id.toChatId(), stickerSetName, "Sticker set by ${me.firstName}", it.content.media.stickerFormat, listOf( - when (sticker) { - is CustomEmojiSticker -> InputSticker.WithKeywords.CustomEmoji( - downloadFileToTemp(sticker.fileId).asMultipartFile(), - sticker.emoji ?.let(::listOf) ?: emptyList(), - emptyList() - ) - is MaskSticker -> TODO() - is RegularSticker -> TODO() - is UnknownSticker -> TODO() - } + newSticker ), - sticker - ) + (sticker as? CustomEmojiSticker) ?.needsRepainting ?: false + ).also { _ -> + reply( + it, + getStickerSet(stickerSetName).stickers.first() + ) + } } } - } -} \ No newline at end of file + }.second.join() +} diff --git a/WebApp/README.md b/WebApp/README.md index 4275aab..aede3d6 100644 --- a/WebApp/README.md +++ b/WebApp/README.md @@ -12,6 +12,6 @@ What is there in this module: ## How to run -```kotlin +```bash ./gradlew run --args="TOKEN WEB_APP_ADDRESS" ``` diff --git a/gradle.properties b/gradle.properties index d217a5a..64745c5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx1g kotlin_version=1.8.10 -telegram_bot_api_version=7.0.0-branch_7.0.0-build1551 +telegram_bot_api_version=7.0.0 micro_utils_version=0.17.5 serialization_version=1.5.0 ktor_version=2.2.4