feat: migrate to ktgram

This commit is contained in:
Yuri Torlopov 2024-06-19 13:26:38 +03:00
parent 0df3df53a7
commit 55a5a3e5d6
8 changed files with 141 additions and 131 deletions

View file

@ -9,11 +9,12 @@ version = "0.0.1"
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://jitpack.io")
} }
dependencies { dependencies {
implementation("org.telegram:telegrambots-longpolling:7.4.2") implementation("com.github.lavafrai:ktgram:1.0.0")
implementation("org.telegram:telegrambots-client:7.4.2")
testImplementation(kotlin("test")) testImplementation(kotlin("test"))
} }
@ -23,5 +24,5 @@ tasks.test {
} }
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8" kotlinOptions.jvmTarget = "17"
} }

View file

@ -1,73 +1,14 @@
package me.theentropyshard.kvinchik package me.theentropyshard.kvinchik
import me.theentropyshard.kvinchik.database.Database import ru.lavafrai.ktgram.client.Bot
import me.theentropyshard.kvinchik.database.impl.RuntimeDatabase import ru.lavafrai.ktgram.dispatcher.routing
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
fun main() {
val bot = Bot(System.getenv("BOT_TOKEN"))
class Kvinchik(token: String) : LongPollingSingleThreadUpdateConsumer { bot.dispatcher.routing {
private val database: Database routing()
private val client: TelegramClient
init {
this.database = RuntimeDatabase()
this.client = OkHttpTelegramClient(token)
} }
override fun consume(update: Update) { bot.runPolling()
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()
}
}
} }

View file

@ -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()
}
}

View file

@ -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)
}

View file

@ -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()
}

View file

@ -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<KvinchikUser>
}

View file

@ -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<KvinchikUser>
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<KvinchikUser> {
return this.users
}
}

View file

@ -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
)