PlaguBot/bot/src/main/kotlin/dev/inmo/plagubot/PlaguBot.kt

123 lines
4.1 KiB
Kotlin
Raw Normal View History

2021-04-03 16:04:18 +00:00
package dev.inmo.plagubot
2022-06-11 13:15:09 +00:00
import dev.inmo.kslog.common.*
import dev.inmo.micro_utils.common.Warning
import dev.inmo.micro_utils.coroutines.runCatchingSafely
2022-08-13 14:09:21 +00:00
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
import dev.inmo.plagubot.config.*
2022-05-13 07:04:49 +00:00
import dev.inmo.tgbotapi.bot.ktor.telegramBot
2022-05-16 17:58:16 +00:00
import dev.inmo.tgbotapi.extensions.api.webhook.deleteWebhook
2022-08-13 14:09:21 +00:00
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
2022-05-16 14:07:57 +00:00
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
2021-04-03 16:04:18 +00:00
import kotlinx.coroutines.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
2022-05-16 14:07:57 +00:00
import kotlinx.serialization.json.JsonObject
2021-04-03 16:04:18 +00:00
import org.jetbrains.exposed.sql.Database
2022-05-16 17:58:16 +00:00
import org.koin.core.Koin
2022-05-16 14:07:57 +00:00
import org.koin.core.KoinApplication
import org.koin.core.context.GlobalContext
2022-05-16 17:58:16 +00:00
import org.koin.core.module.Module
import org.koin.core.scope.Scope
2022-05-16 14:07:57 +00:00
import org.koin.dsl.module
2021-04-03 16:04:18 +00:00
2022-05-16 17:58:16 +00:00
val Scope.plagubot: PlaguBot
2022-05-16 14:07:57 +00:00
get() = get()
2021-04-03 16:04:18 +00:00
val Koin.plagubot: PlaguBot
get() = get()
@OptIn(Warning::class)
2021-04-03 16:04:18 +00:00
@Serializable
data class PlaguBot(
2022-05-16 14:07:57 +00:00
private val json: JsonObject,
2021-04-03 16:04:18 +00:00
private val config: Config
) : Plugin {
@Transient
private val bot = telegramBot(config.botToken)
2022-05-16 17:58:16 +00:00
override fun Module.setupDI(database: Database, params: JsonObject) {
single { config }
single { config.plugins }
single { config.databaseConfig }
single { config.databaseConfig.database }
single { defaultJsonFormat }
single { this@PlaguBot }
includes(
2022-05-16 18:08:45 +00:00
config.plugins.mapNotNull {
runCatching {
module {
with(it) {
setupDI(database, params)
}
2022-05-16 17:58:16 +00:00
}
2022-05-16 18:08:45 +00:00
}.onFailure { e ->
2022-06-11 13:19:19 +00:00
logger.w("Unable to load DI part of $it", e)
2022-05-16 18:08:45 +00:00
}.getOrNull()
2022-05-16 17:58:16 +00:00
}
)
}
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
config.plugins.map { plugin ->
launch {
runCatchingSafely {
logger.i("Start loading of $plugin")
with(plugin) {
setupBotPlugin(koin)
}
}.onFailure { e ->
logger.w("Unable to load bot part of $plugin", e)
}.onSuccess {
logger.i("Complete loading of $plugin")
2022-05-16 18:08:45 +00:00
}
2022-05-16 17:58:16 +00:00
}
}.joinAll()
2021-04-03 16:04:18 +00:00
}
/**
* This method will create an [Job] which will be the main [Job] of ran instance
*/
suspend fun start(
2022-05-16 17:58:16 +00:00
scope: CoroutineScope = CoroutineScope(Dispatchers.IO)
2022-05-16 14:07:57 +00:00
): Job {
2022-06-11 13:19:19 +00:00
logger.i("Start initialization")
2022-05-16 14:07:57 +00:00
val koinApp = KoinApplication.init()
koinApp.modules(
module {
2022-05-16 17:58:16 +00:00
setupDI(config.databaseConfig.database, json)
2022-05-16 14:07:57 +00:00
}
)
2022-06-11 13:19:19 +00:00
logger.i("Modules loaded")
2022-05-16 17:58:16 +00:00
GlobalContext.startKoin(koinApp)
2022-06-11 13:19:19 +00:00
logger.i("Koin started")
2022-05-16 14:07:57 +00:00
lateinit var behaviourContext: BehaviourContext
2022-08-13 14:09:21 +00:00
bot.buildBehaviourWithFSM(
scope = scope,
defaultExceptionsHandler = {
logger.e("Something went wrong", it)
},
statesManager = koinApp.koin.getOrNull<StatesManager<State>>() ?: DefaultStatesManager(
InMemoryDefaultStatesManagerRepo<State>()
),
onStateHandlingErrorHandler = koinApp.koin.getOrNull<FallbackStateHandler<State>>() ?: { state, e ->
logger.eS(e) { "Unable to handle state $state" }
null
}
) {
2022-06-11 13:19:19 +00:00
logger.i("Start setup of bot part")
2022-05-16 14:07:57 +00:00
behaviourContext = this
2022-05-16 17:58:16 +00:00
setupBotPlugin(koinApp.koin)
deleteWebhook()
2022-05-16 14:07:57 +00:00
}
2022-06-11 13:19:19 +00:00
logger.i("Behaviour builder has been setup")
2022-05-16 18:08:45 +00:00
return bot.startGettingOfUpdatesByLongPolling(scope = behaviourContext, updatesFilter = behaviourContext).also {
2022-06-11 13:19:19 +00:00
logger.i("Long polling has been started")
2022-05-16 18:08:45 +00:00
}
2021-04-03 16:04:18 +00:00
}
}