replace plagubot on top of hierarchy

This commit is contained in:
2023-10-06 21:26:09 +06:00
parent 669263398d
commit 6f0bc12181
3 changed files with 2 additions and 2 deletions

95
docs/plagubot/index.md Normal file
View File

@@ -0,0 +1,95 @@
# PlaguBot
[PlaguBot](https://github.com/InsanusMokrassar/PlaguBot) is a small framework for unifying developing of modules of bots. It is built with two parts:
* [Plugin](https://github.com/InsanusMokrassar/PlaguBot/blob/master/plugin/src/main/kotlin/dev/inmo/plagubot/Plugin.kt)
* [Bot](https://github.com/InsanusMokrassar/PlaguBot/tree/master/bot/src/main/kotlin/dev/inmo/plagubot)
## Plugin
Plugin is a partially independent part of bot. Plugin have several parts:
* `setupDI` - this method should be used to configure DI part of module
* `setupBotPlugin` - method to start/configure your bot actions
Plugin realization should be an `object` or `class` with empty constructor.
## Bot
Most important of bot is `main` function (full reference: `dev.inmo.plagubot.AppKt`). It consumes one argument - path to config.
Bot is initializing with the next algorithm:
```mermaid
flowchart TB
main["Main"]
Join["Endless join bot work"]
subgraph ConfigReading
direction LR
ConfigJsonParsing["Parsing to Json"]
ConfigParsing["Parsing to global config"]
ConfigJsonParsing --> ConfigParsing
end
ConfigReading["Reading of config"]
BotConstructorCalling["Calling of PlaguBot constructor"]
subgraph BotStart
direction TB
BotStartKoinAppInit["Initialization of koin app"]
subgraph BotStartSetupDI
direction LR
subgraph BotStartSetupDIPutDefaults["Put defaults in DI"]
direction LR
BotStartSetupDIPutDefaultsConfig["Config"]
BotStartSetupDIPutDefaultsPluginsList["Plugins list"]
BotStartSetupDIPutDefaultsDatabaseConfig["Database Config"]
BotStartSetupDIPutDefaultsDefaultJson["Default Json"]
BotStartSetupDIPutDefaultsPlagubot["PlaguBot itself"]
BotStartSetupDIPutDefaultsTelegramBot["TelegramBot"]
end
BotStartSetupDIIncludes["`Synchronous (in queue) registration of all plugins __setupDI__ modules`"]
BotStartSetupDIPutDefaults --> BotStartSetupDIIncludes
end
BotStartKoinAppStart["`Starting of koin application. Since this step all modules from __setupDI__ of plugins will be available`"]
subgraph BotStartBehaviourContextInitialization["Initialization of behaviour context"]
direction TB
BotStartBehaviourContextInitializationStatesManager["`Get from DI or create default **DefaultStatesManagerRepo**`"]
BotStartBehaviourContextInitializationStatesManagerRepo["`Get from DI or create default **StatesManagerRepo**`"]
BotStartBehaviourContextInitializationStatesManagerUsedCondition{"Is the default one used?"}
BotStartBehaviourContextInitializationOnStartConflictsResolver["Getting of all OnStartContextsConflictResolver"]
BotStartBehaviourContextInitializationOnUpdateConflictsResolver["Getting of all OnUpdateContextsConflictResolver"]
BotStartBehaviourContextInitializationStateHandlingErrorHandler["`Get from DI or create default **StateHandlingErrorHandler**`"]
subgraph BotStartBehaviourContextInitializationSetupPlugins["Plugins bot functionality init"]
BotStartBehaviourContextInitializationSetupPluginsSetupBotPlugin["`Call **setupBotPlugin** for each plugin`"]
end
BotStartBehaviourContextInitializationStatesManager --> BotStartBehaviourContextInitializationStatesManagerUsedCondition
BotStartBehaviourContextInitializationStatesManagerUsedCondition --"Yes"--> BotStartBehaviourContextInitializationStatesManagerRepo
BotStartBehaviourContextInitializationStatesManagerUsedCondition --"No"--> BotStartBehaviourContextInitializationStateHandlingErrorHandler
BotStartBehaviourContextInitializationStatesManagerRepo --> BotStartBehaviourContextInitializationOnStartConflictsResolver
BotStartBehaviourContextInitializationOnStartConflictsResolver --> BotStartBehaviourContextInitializationOnUpdateConflictsResolver
BotStartBehaviourContextInitializationOnUpdateConflictsResolver --> BotStartBehaviourContextInitializationStateHandlingErrorHandler
BotStartBehaviourContextInitializationStateHandlingErrorHandler --> BotStartBehaviourContextInitializationSetupPlugins
end
BotStartDeleteWebhook["Delete webhooks"]
BotStartStartLongPolling["Start long polling"]
BotStartKoinAppInit --> BotStartSetupDI
BotStartSetupDI --> BotStartKoinAppStart
BotStartKoinAppStart --> BotStartBehaviourContextInitialization
BotStartBehaviourContextInitialization --> BotStartDeleteWebhook
BotStartDeleteWebhook --> BotStartStartLongPolling
end
main --> ConfigReading
ConfigReading --> BotConstructorCalling
BotConstructorCalling --> BotStart
BotStart --> Join
```

View File

@@ -0,0 +1,148 @@
# Opportunities out of the box
There are several important opportunities out of the box:
* Database access
* Config access
* Bot setup
* Json format
* Bot itself
## Database access
You may access database in your plugin via koin in `setupBotPlugin` or as parameter in `setupDI`:
```kotlin
object YourPlugin : Plugin {
// ...
override fun Module.setupDI(
database: Database, // database
params: JsonObject
) {
// ...
}
}
```
It is simple [Exposed](https://github.com/JetBrains/Exposed) database and you may use it in your tables.
## Config access
As you may see, in the `setupDI` function we also have `params` parameter with source configuration json. In case
you wish to declare and work with your own config in plugin, you may use next snippet:
```kotlin
object YourPlugin : Plugin {
@Serializable
data class MyConfig(
val param1: String,
val param2: Int,
)
// ...
override fun Module.setupDI(
database: Database, // database
params: JsonObject
) {
single {
get<Json>().decodeFromJsonElement(MyConfig.serializer(), params) // register from root (1)
}
// OR
single {
get<Json>().decodeFromJsonElement(MyConfig.serializer(), params["yourplugin"]!!) // register from field "yourplugin" (2)
}
// ...
}
override suspend fun BehaviourContext.setupBotPlugin(
koin: Koin
) {
koin.get<MyConfig>() // getting of registered config
}
}
```
1. In this case your config will looks like:
```json
{
"params1": "SomeString",
"params2": 42
}
```
2. In this case your config will looks like:
```json
{
"yourplugin": {
"params1": "SomeString",
"params2": 42
}
}
```
## Bot setup
Out of the box you may setup several things in bot:
<div class="annotate" markdown>
* `StatesManager<State>` (1)
* `DefaultStatesManagerRepo<State>` (2)
* Any amount of `OnStartContextsConflictResolver` (3)
* Any amount of `OnUpdateContextsConflictResolver` (4)
* `StateHandlingErrorHandler<State>` (5)
</div>
1. For this use next code in `setupDI`:
```kotlin
// Your plugin
override fun Module.setupDI(database: Database, params: JsonObject) {
single<StatesManager<State>> {
// Your StatesManager<State> initialization
}
}
```
2. For this use next code in `setupDI`:
```kotlin
// Your plugin
override fun Module.setupDI(database: Database, params: JsonObject) {
single<DefaultStatesManagerRepo<State>> {
// Your DefaultStatesManagerRepo<State> initialization
}
}
```
3. You may declare any amount of `OnStartContextsConflictResolver`. `PlaguBot` will take first non-null result of
resolvers from DI and use in default states manager. To declare, use next snippet:
```kotlin
// Your plugin
override fun Module.setupDI(database: Database, params: JsonObject) {
singleWithRandomQualifier<OnStartContextsConflictResolver> {
OnStartContextsConflictResolver { old, new ->
// null|true|false
}
}
}
```
4. You may declare any amount of `OnUpdateContextsConflictResolver`. `PlaguBot` will take first non-null result of
resolvers from DI and use in default states manager. To declare, use next snippet:
```kotlin
// Your plugin
override fun Module.setupDI(database: Database, params: JsonObject) {
singleWithRandomQualifier<OnUpdateContextsConflictResolver> {
OnUpdateContextsConflictResolver { old, new, currentStateOnContext ->
// null|true|false
}
}
}
```
5. You may declare only one `StateHandlingErrorHandler<State>`. This handler will be called each time when some state
will be handled with exception and may return `null` or new state instead old one:
```kotlin
// Your plugin
override fun Module.setupDI(database: Database, params: JsonObject) {
single<StateHandlingErrorHandler<State>> {
StateHandlingErrorHandler<State> { state, throwable ->
// null or State
}
}
}
```