diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bd5d32..4118b17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## 0.1.7 +* `PlaguBot` + * New class `PlaguBot` (😊) + * `initPlaguBot` is deprecated + * New shortcut for params - `plagubot`. `PlaguBot` class can be put inside other plagubot + for additional opportunities + ## 0.1.6 * `Versions` diff --git a/bot/src/main/kotlin/dev/inmo/plagubot/App.kt b/bot/src/main/kotlin/dev/inmo/plagubot/App.kt index 78ee034..3676fc5 100644 --- a/bot/src/main/kotlin/dev/inmo/plagubot/App.kt +++ b/bot/src/main/kotlin/dev/inmo/plagubot/App.kt @@ -1,38 +1,22 @@ package dev.inmo.plagubot -import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions import dev.inmo.plagubot.config.* import dev.inmo.plagubot.config.configJsonFormat -import dev.inmo.tgbotapi.bot.Ktor.telegramBot -import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands -import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour -import dev.inmo.tgbotapi.types.botCommandsLimit import kotlinx.coroutines.* import kotlinx.serialization.InternalSerializationApi import java.io.File +@Deprecated( + "This method is redundant due to new class PlaguBot", + ReplaceWith( + "PlaguBot(config).start(scope)", + "dev.inmo.plagubot.PlaguBot" + ) +) suspend inline fun initPlaguBot( config: Config, scope: CoroutineScope = CoroutineScope(Dispatchers.Default) -): Job { - val bot = telegramBot(config.botToken) - - val paramsMap = config.params ?.toMap() ?: emptyMap() - val database = config.params ?.database ?: config.database.database - return bot.buildBehaviour(scope) { - val commands = config.plugins.flatMap { - it.apply { invoke(database, paramsMap) } - it.getCommands() - }.let { - val futureUnavailable = it.drop(botCommandsLimit.last) - if (futureUnavailable.isNotEmpty()) { - println("Next commands are out of range in setting command request and will be unavailable from autocompleting: ${futureUnavailable}") - } - it.take(botCommandsLimit.last) - } - safelyWithoutExceptions { setMyCommands(commands) } - } -} +): Job = PlaguBot(config).start(scope) /** * This method by default expects one argument in [args] field: path to config @@ -43,6 +27,5 @@ suspend fun main(args: Array) { val file = File(configPath) val config = configJsonFormat.decodeFromString(ConfigSerializer, file.readText()) - val scope = CoroutineScope(Dispatchers.Default) - initPlaguBot(config, scope).join() + PlaguBot(config).start().join() } diff --git a/bot/src/main/kotlin/dev/inmo/plagubot/PlaguBot.kt b/bot/src/main/kotlin/dev/inmo/plagubot/PlaguBot.kt new file mode 100644 index 0000000..ca7e3b5 --- /dev/null +++ b/bot/src/main/kotlin/dev/inmo/plagubot/PlaguBot.kt @@ -0,0 +1,56 @@ +package dev.inmo.plagubot + +import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions +import dev.inmo.plagubot.config.Config +import dev.inmo.plagubot.config.database +import dev.inmo.tgbotapi.bot.Ktor.telegramBot +import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour +import dev.inmo.tgbotapi.types.BotCommand +import dev.inmo.tgbotapi.types.botCommandsLimit +import kotlinx.coroutines.* +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import org.jetbrains.exposed.sql.Database + +const val DefaultPlaguBotParamsKey = "plagubot" +val Map.plagubot + get() = get(DefaultPlaguBotParamsKey) as? PlaguBot + +@Serializable +data class PlaguBot( + private val config: Config +) : Plugin { + @Transient + private val bot = telegramBot(config.botToken) + @Transient + private val paramsMap = config.params ?.toMap() ?: emptyMap() + @Transient + private val database = config.params ?.database ?: config.database.database + + override suspend fun getCommands(): List = config.plugins.flatMap { + it.getCommands() + } + + override suspend fun BehaviourContext.invoke(database: Database, params: Map) { + config.plugins.forEach { + it.apply { invoke(database, params) } + } + val commands = getCommands() + val futureUnavailable = commands.drop(botCommandsLimit.last) + if (futureUnavailable.isNotEmpty()) { + println("Next commands are out of range in setting command request and will be unavailable from autocompleting: $futureUnavailable") + } + safelyWithoutExceptions { setMyCommands(commands.take(botCommandsLimit.last)) } + } + + /** + * This method will create an [Job] which will be the main [Job] of ran instance + */ + suspend fun start( + scope: CoroutineScope = CoroutineScope(Dispatchers.Default) + ): Job = bot.buildBehaviour(scope) { + invoke(database, paramsMap) + } +}