From 522d1b55ba706b1c8e960a9d83eb336ebb9d44b8 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 30 Jun 2021 13:12:15 +0600 Subject: [PATCH] add example with oneof and fsm --- FSMBot/README.md | 10 +++ FSMBot/build.gradle | 22 +++++++ FSMBot/src/main/kotlin/SimpleFSMBot.kt | 90 ++++++++++++++++++++++++++ gradle.properties | 3 +- settings.gradle | 1 + 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 FSMBot/README.md create mode 100644 FSMBot/build.gradle create mode 100644 FSMBot/src/main/kotlin/SimpleFSMBot.kt diff --git a/FSMBot/README.md b/FSMBot/README.md new file mode 100644 index 0000000..9ee12ce --- /dev/null +++ b/FSMBot/README.md @@ -0,0 +1,10 @@ +# FSM + +This bot contains an example of working with FSM included in project +[MicroUtils](https://github.com/InsanusMokrassar/MicroUtils) + +## Launch + +```bash +../gradlew run --args="BOT_TOKEN" +``` diff --git a/FSMBot/build.gradle b/FSMBot/build.gradle new file mode 100644 index 0000000..a25fd20 --- /dev/null +++ b/FSMBot/build.gradle @@ -0,0 +1,22 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName="HelloBotKt" + + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + + implementation "dev.inmo:tgbotapi:$telegram_bot_api_version" + implementation "dev.inmo:micro_utils.fsm.common:$micro_utils_version" +} diff --git a/FSMBot/src/main/kotlin/SimpleFSMBot.kt b/FSMBot/src/main/kotlin/SimpleFSMBot.kt new file mode 100644 index 0000000..28912c9 --- /dev/null +++ b/FSMBot/src/main/kotlin/SimpleFSMBot.kt @@ -0,0 +1,90 @@ +import dev.inmo.micro_utils.fsm.common.State +import dev.inmo.micro_utils.fsm.common.dsl.buildFSM +import dev.inmo.micro_utils.fsm.common.dsl.strictlyOn +import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.api.send.sendMessage +import dev.inmo.tgbotapi.extensions.behaviour_builder.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.command +import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams +import dev.inmo.tgbotapi.extensions.utils.formatting.* +import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat +import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage +import dev.inmo.tgbotapi.types.message.content.TextContent +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent +import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers + +sealed interface State : State +data class ExpectContentOrStopState(override val context: ChatId, val sourceMessage: CommonMessage) : State +data class StopState(override val context: ChatId) : State + +fun TextContent.containsStopCommand() = parseCommandsWithParams().keys.firstOrNull { it == "stop" } != null + +suspend fun main(args: Array) { + val botToken = args.first() + + telegramBotWithBehaviour(botToken, CoroutineScope(Dispatchers.IO)) { + val fsm = buildFSM { + strictlyOn { + sendMessage( + it.context, + buildEntities { + +"Send me some content or " + botCommand("stop") + +" if you want to stop sending" + } + ) + + val content = oneOf( + parallel { + waitContentMessage(includeMediaGroups = false) { if (chat.id == it.context) content else null }.also(::println) + }, + parallel { + waitMediaGroup { chat ?.id == it.context }.also(::println) + }, + parallel { + waitText { if (content.containsStopCommand()) content else null }.also(::println) + } + ).first() + + when { + content is TextContent && content.containsStopCommand() -> StopState(it.context) // assume we got "stop" command + content is List<*> -> { // assume it is media group + val casted = (content as List) + + reply(it.sourceMessage, "Ok, I got this media group and now will resend it to you") + sendMediaGroup(it.context, casted.map { it.toMediaGroupMemberInputMedia() }) + + it + } + content is MessageContent -> { + + reply(it.sourceMessage, "Ok, I got this content and now will resend it to you") + execute(content.createResend(it.context)) + + it + } + else -> { + sendMessage(it.context, "Unknown internal error") + it + } + } + } + strictlyOn { + sendMessage(it.context, "You have stopped sending of content") + + null + } + } + + command("start") { + fsm.startChain(ExpectContentOrStopState(it.chat.id, it)) + } + + fsm.start(this) + }.second.join() +} diff --git a/gradle.properties b/gradle.properties index 890916b..d4b82fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,5 @@ kotlin.code.style=official org.gradle.parallel=true kotlin_version=1.5.20 -telegram_bot_api_version=0.35.1 +telegram_bot_api_version=0.35.1-branch_0.35.1-build280 +micro_utils_version=0.5.15 diff --git a/settings.gradle b/settings.gradle index 48cdeb2..fb925d4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,3 +6,4 @@ include ":FilesLoaderBot" include ":ResenderBot:ResenderBotLib" include ":ResenderBot:jvm_launcher" include ":SlotMachineDetectorBot" +include ":FSMBot"