From 55a5a3e5d689ec159e396b613c1cdb96c3557814 Mon Sep 17 00:00:00 2001 From: TheEntropyShard Date: Wed, 19 Jun 2024 13:26:38 +0300 Subject: [PATCH] feat: migrate to ktgram --- build.gradle.kts | 7 +- .../me/theentropyshard/kvinchik/Kvinchik.kt | 75 ++--------- .../me/theentropyshard/kvinchik/Main.kt | 14 --- .../me/theentropyshard/kvinchik/Routing.kt | 117 ++++++++++++++++++ .../theentropyshard/kvinchik/StartStates.kt | 12 ++ .../kvinchik/database/Database.kt | 11 -- .../kvinchik/database/impl/RuntimeDatabase.kt | 27 ---- .../kvinchik/entity/KvinchikUser.kt | 9 -- 8 files changed, 141 insertions(+), 131 deletions(-) delete mode 100644 src/main/kotlin/me/theentropyshard/kvinchik/Main.kt create mode 100644 src/main/kotlin/me/theentropyshard/kvinchik/Routing.kt create mode 100644 src/main/kotlin/me/theentropyshard/kvinchik/StartStates.kt delete mode 100644 src/main/kotlin/me/theentropyshard/kvinchik/database/Database.kt delete mode 100644 src/main/kotlin/me/theentropyshard/kvinchik/database/impl/RuntimeDatabase.kt delete mode 100644 src/main/kotlin/me/theentropyshard/kvinchik/entity/KvinchikUser.kt diff --git a/build.gradle.kts b/build.gradle.kts index b1ce910..def09bf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,11 +9,12 @@ version = "0.0.1" repositories { mavenCentral() + + maven("https://jitpack.io") } dependencies { - implementation("org.telegram:telegrambots-longpolling:7.4.2") - implementation("org.telegram:telegrambots-client:7.4.2") + implementation("com.github.lavafrai:ktgram:1.0.0") testImplementation(kotlin("test")) } @@ -23,5 +24,5 @@ tasks.test { } tasks.withType { - kotlinOptions.jvmTarget = "1.8" + kotlinOptions.jvmTarget = "17" } \ No newline at end of file diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/Kvinchik.kt b/src/main/kotlin/me/theentropyshard/kvinchik/Kvinchik.kt index 45d4459..f85684d 100644 --- a/src/main/kotlin/me/theentropyshard/kvinchik/Kvinchik.kt +++ b/src/main/kotlin/me/theentropyshard/kvinchik/Kvinchik.kt @@ -1,73 +1,14 @@ package me.theentropyshard.kvinchik -import me.theentropyshard.kvinchik.database.Database -import me.theentropyshard.kvinchik.database.impl.RuntimeDatabase -import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient -import org.telegram.telegrambots.longpolling.util.LongPollingSingleThreadUpdateConsumer -import org.telegram.telegrambots.meta.api.methods.send.SendMessage -import org.telegram.telegrambots.meta.api.objects.Update -import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup -import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton -import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardRow -import org.telegram.telegrambots.meta.exceptions.TelegramApiException -import org.telegram.telegrambots.meta.generics.TelegramClient +import ru.lavafrai.ktgram.client.Bot +import ru.lavafrai.ktgram.dispatcher.routing +fun main() { + val bot = Bot(System.getenv("BOT_TOKEN")) -class Kvinchik(token: String) : LongPollingSingleThreadUpdateConsumer { - private val database: Database - private val client: TelegramClient - - init { - this.database = RuntimeDatabase() - this.client = OkHttpTelegramClient(token) + bot.dispatcher.routing { + routing() } - override fun consume(update: Update) { - if (update.hasMessage()) { - if (update.message.hasText()) { - this.handleTextMessage(update) - } - } - } - - private fun handleTextMessage(update: Update) { - when (update.message.text) { - "/start" -> { - this.handleStart(update) - } - - else -> {} - } - } - - private fun handleStart(update: Update) { - if (!this.database.userExists(update.message.from.id)) { - this.askUserToCreateProfile(update.message.chatId.toString(), update.message.from.userName) - } else { - - } - } - - private fun askUserToCreateProfile(chatId: String, currentUserName: String) { - val askNameMessage = SendMessage.builder() - .chatId(chatId) - .text("How should I call you?") - .replyMarkup( - InlineKeyboardMarkup.builder() - .keyboardRow( - InlineKeyboardRow( - InlineKeyboardButton.builder() - .text(currentUserName) - .callbackData("name_stage") - .build() - ) - ).build() - ).build() - - try { - this.client.execute(askNameMessage) - } catch (e: TelegramApiException) { - e.printStackTrace() - } - } -} \ No newline at end of file + bot.runPolling() +} diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/Main.kt b/src/main/kotlin/me/theentropyshard/kvinchik/Main.kt deleted file mode 100644 index c0dcad8..0000000 --- a/src/main/kotlin/me/theentropyshard/kvinchik/Main.kt +++ /dev/null @@ -1,14 +0,0 @@ -package me.theentropyshard.kvinchik - -import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication -import org.telegram.telegrambots.meta.exceptions.TelegramApiException - -fun main() { - try { - val token = System.getenv("BOT_TOKEN") - val application = TelegramBotsLongPollingApplication() - application.registerBot(token, Kvinchik(token)) - } catch (e: TelegramApiException) { - e.printStackTrace() - } -} diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/Routing.kt b/src/main/kotlin/me/theentropyshard/kvinchik/Routing.kt new file mode 100644 index 0000000..5157aa8 --- /dev/null +++ b/src/main/kotlin/me/theentropyshard/kvinchik/Routing.kt @@ -0,0 +1,117 @@ +package me.theentropyshard.kvinchik + +import ru.lavafrai.ktgram.dispatcher.* +import ru.lavafrai.ktgram.stateMachine.clearState +import ru.lavafrai.ktgram.stateMachine.data +import ru.lavafrai.ktgram.stateMachine.setState +import ru.lavafrai.ktgram.types.Chat +import ru.lavafrai.ktgram.types.inputfile.InputFile +import ru.lavafrai.ktgram.types.media.PhotoSize +import ru.lavafrai.ktgram.types.media.largest +import ru.lavafrai.ktgram.types.replymarkup.inlineKeyboard.inlineKeyboard + +fun Router<*>.routing() { + command("start") { + text { + handle { + val keyboard = inlineKeyboard { + row { + button(update.message!!.from!!.firstName, "username") + } + } + + data.clear() + message.answer("Hello! How should I call you?", replyMarkup = keyboard) + setState(StartStates.WaitingName) + } + } + } + + state(StartStates.WaitingName) { + callbackQuery("username") { + handle { + val name = update.from!!.firstName + data.set("name", name) + query.message!!.answer("Nice to meet you, $name! Now I need to know your age.") + setState(StartStates.WaitingAge) + query.answer() + } + } + + text { + handle { + val name = message.text!! + data.set("name", name) + setState(StartStates.WaitingAge) + message.answer("Nice to meet you, $name! Now I need to know your age.") + } + } + } + + state(StartStates.WaitingAge) { + text { + handle { + val age = message.text!! + data.set("age", age) + setState(StartStates.WaitingCity) + message.answer("Well, in which city do you live?") + } + } + } + + state(StartStates.WaitingCity) { + text { + handle { + val city = message.text!! + data.set("city", city) + setState(StartStates.WaitingDescription) + message.answer("Could you now tell me something about yourself?") + } + } + } + + state(StartStates.WaitingDescription) { + text { + handle { + val description = message.text!! + data.set("description", description) + setState(StartStates.Registered) + message.answer("And the last thing - I need to know how do you look like. Please, send a photo of yourself.") + } + } + } + + state(StartStates.Registered) { + photo { + handle { + clearState() + + val photo = message.photo!!.largest() + message.answer("Now you are registered!") + + sendSummary( + message.chat, + data.get("name")!!, + data.get("age")!!.toInt(), + data.get("city")!!, + data.get("description")!!, + photo + ) + + data.clear() + } + } + } +} + +suspend fun sendSummary(chat: Chat, name: String, age: Int, city: String, description: String, photo: PhotoSize) { + val summary = buildString { + append("Summary: ") + append("Name: $name ") + append("Age: $age ") + append("City: $city ") + append("Description: $description") + } + + chat.sendPhoto(photo = InputFile.fromFileId(photo.fileId), caption = summary) +} \ No newline at end of file diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/StartStates.kt b/src/main/kotlin/me/theentropyshard/kvinchik/StartStates.kt new file mode 100644 index 0000000..16446b9 --- /dev/null +++ b/src/main/kotlin/me/theentropyshard/kvinchik/StartStates.kt @@ -0,0 +1,12 @@ +package me.theentropyshard.kvinchik + +import ru.lavafrai.ktgram.stateMachine.State + +sealed class StartStates { + object WaitingName : State() + object WaitingAge : State() + object WaitingCity : State() + object WaitingDescription : State() + object WaitingPhoto : State() + object Registered : State() +} \ No newline at end of file diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/database/Database.kt b/src/main/kotlin/me/theentropyshard/kvinchik/database/Database.kt deleted file mode 100644 index 2ee1f9e..0000000 --- a/src/main/kotlin/me/theentropyshard/kvinchik/database/Database.kt +++ /dev/null @@ -1,11 +0,0 @@ -package me.theentropyshard.kvinchik.database - -import me.theentropyshard.kvinchik.entity.KvinchikUser - -interface Database { - fun userExists(id: Long): Boolean - - fun saveUser(user: KvinchikUser) - - fun getUsers(): List -} \ No newline at end of file diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/database/impl/RuntimeDatabase.kt b/src/main/kotlin/me/theentropyshard/kvinchik/database/impl/RuntimeDatabase.kt deleted file mode 100644 index 25dfdeb..0000000 --- a/src/main/kotlin/me/theentropyshard/kvinchik/database/impl/RuntimeDatabase.kt +++ /dev/null @@ -1,27 +0,0 @@ -package me.theentropyshard.kvinchik.database.impl - -import me.theentropyshard.kvinchik.database.Database -import me.theentropyshard.kvinchik.entity.KvinchikUser -import me.theentropyshard.kvinchik.util.search - -class RuntimeDatabase : Database { - private val users: MutableList - - init { - this.users = ArrayList() - } - - override fun userExists(id: Long): Boolean = users.search { it.id == id } != null - - override fun saveUser(user: KvinchikUser) { - if (this.userExists(user.id)) { - return - } - - this.users.add(user) - } - - override fun getUsers(): List { - return this.users - } -} diff --git a/src/main/kotlin/me/theentropyshard/kvinchik/entity/KvinchikUser.kt b/src/main/kotlin/me/theentropyshard/kvinchik/entity/KvinchikUser.kt deleted file mode 100644 index 6c3697b..0000000 --- a/src/main/kotlin/me/theentropyshard/kvinchik/entity/KvinchikUser.kt +++ /dev/null @@ -1,9 +0,0 @@ -package me.theentropyshard.kvinchik.entity - -data class KvinchikUser( - val id: Long, - val name: String, - val age: Int, - val city: String, - val description: String -)