mirror of
				https://github.com/InsanusMokrassar/TelegramBotAPI.git
				synced 2025-11-04 06:00:15 +00:00 
			
		
		
		
	several actualizations for behaviour builder with fsm
This commit is contained in:
		@@ -21,6 +21,8 @@ private suspend fun <I : State> BehaviourContextWithFSM.launchStateHandling(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
 | 
					interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
 | 
				
			||||||
 | 
					    suspend fun start() = start(this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun copy(
 | 
					    override fun copy(
 | 
				
			||||||
        bot: TelegramBot,
 | 
					        bot: TelegramBot,
 | 
				
			||||||
        scope: CoroutineScope,
 | 
					        scope: CoroutineScope,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,18 @@
 | 
				
			|||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder
 | 
					package dev.inmo.tgbotapi.extensions.behaviour_builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.inmo.micro_utils.coroutines.ContextSafelyExceptionHandler
 | 
				
			||||||
 | 
					import dev.inmo.micro_utils.coroutines.ExceptionHandler
 | 
				
			||||||
import dev.inmo.micro_utils.fsm.common.*
 | 
					import dev.inmo.micro_utils.fsm.common.*
 | 
				
			||||||
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
 | 
					import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
 | 
				
			||||||
import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
 | 
					import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
 | 
				
			||||||
import dev.inmo.tgbotapi.bot.TelegramBot
 | 
					import dev.inmo.tgbotapi.bot.TelegramBot
 | 
				
			||||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
 | 
					import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
 | 
				
			||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
 | 
					import dev.inmo.tgbotapi.types.update.abstracts.Update
 | 
				
			||||||
import kotlinx.coroutines.CoroutineScope
 | 
					import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.utils.PreviewFeature
 | 
				
			||||||
 | 
					import kotlinx.coroutines.*
 | 
				
			||||||
import kotlinx.coroutines.flow.Flow
 | 
					import kotlinx.coroutines.flow.Flow
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					 | 
				
			||||||
import kotlin.reflect.KClass
 | 
					import kotlin.reflect.KClass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BehaviourContextWithFSMBuilder internal constructor(
 | 
					class BehaviourContextWithFSMBuilder internal constructor(
 | 
				
			||||||
@@ -83,9 +87,13 @@ inline fun <reified I : State> BehaviourContextWithFSMBuilder.strictlyOn(handler
 | 
				
			|||||||
suspend fun TelegramBot.buildBehaviourWithFSM(
 | 
					suspend fun TelegramBot.buildBehaviourWithFSM(
 | 
				
			||||||
    upstreamUpdatesFlow: Flow<Update>? = null,
 | 
					    upstreamUpdatesFlow: Flow<Update>? = null,
 | 
				
			||||||
    scope: CoroutineScope = defaultCoroutineScopeProvider(),
 | 
					    scope: CoroutineScope = defaultCoroutineScopeProvider(),
 | 
				
			||||||
 | 
					    statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
 | 
				
			||||||
 | 
					    handlersPreset: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(),
 | 
				
			||||||
    block: suspend BehaviourContextWithFSMBuilder.() -> Unit
 | 
					    block: suspend BehaviourContextWithFSMBuilder.() -> Unit
 | 
				
			||||||
) = BehaviourContextWithFSMBuilder(
 | 
					) = BehaviourContextWithFSMBuilder(
 | 
				
			||||||
    DefaultBehaviourContext(this, scope, upstreamUpdatesFlow = upstreamUpdatesFlow)
 | 
					    DefaultBehaviourContext(this, scope, upstreamUpdatesFlow = upstreamUpdatesFlow),
 | 
				
			||||||
 | 
					    statesManager,
 | 
				
			||||||
 | 
					    handlersPreset
 | 
				
			||||||
).apply { block() }.build()
 | 
					).apply { block() }.build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -98,10 +106,83 @@ suspend fun TelegramBot.buildBehaviourWithFSM(
 | 
				
			|||||||
suspend fun TelegramBot.buildBehaviourWithFSMAndLongPolling(
 | 
					suspend fun TelegramBot.buildBehaviourWithFSMAndLongPolling(
 | 
				
			||||||
    upstreamUpdatesFlow: Flow<Update>? = null,
 | 
					    upstreamUpdatesFlow: Flow<Update>? = null,
 | 
				
			||||||
    scope: CoroutineScope = defaultCoroutineScopeProvider(),
 | 
					    scope: CoroutineScope = defaultCoroutineScopeProvider(),
 | 
				
			||||||
 | 
					    statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
 | 
				
			||||||
 | 
					    presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(),
 | 
				
			||||||
    block: suspend BehaviourContextWithFSMBuilder.() -> Unit
 | 
					    block: suspend BehaviourContextWithFSMBuilder.() -> Unit
 | 
				
			||||||
) = buildBehaviourWithFSM(upstreamUpdatesFlow, scope, block).run {
 | 
					) = buildBehaviourWithFSM(upstreamUpdatesFlow, scope, statesManager, presetHandlers, block).run {
 | 
				
			||||||
    this to scope.launch {
 | 
					    this to scope.launch {
 | 
				
			||||||
        longPolling(this@run, scope = this)
 | 
					        start()
 | 
				
			||||||
        start(this)
 | 
					        longPolling(flowsUpdatesFilter, scope = scope)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Use this method in case you wish to make some additional actions with [flowUpdatesFilter].
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * **WARNING** This method WILL NOT launch any listening of updates. Use something like
 | 
				
			||||||
 | 
					 * [startGettingOfUpdatesByLongPolling] (or just [longPolling]) or tools for work with webhooks
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see BehaviourContext
 | 
				
			||||||
 | 
					 * @see BehaviourContextWithFSM
 | 
				
			||||||
 | 
					 * @see longPolling
 | 
				
			||||||
 | 
					 * @see strictlyOn
 | 
				
			||||||
 | 
					 * @see onStateOrSubstate
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@PreviewFeature
 | 
				
			||||||
 | 
					suspend fun TelegramBot.buildBehaviourWithFSM(
 | 
				
			||||||
 | 
					    flowUpdatesFilter: FlowsUpdatesFilter,
 | 
				
			||||||
 | 
					    scope: CoroutineScope = defaultCoroutineScopeProvider(),
 | 
				
			||||||
 | 
					    defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
 | 
				
			||||||
 | 
					    statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
 | 
				
			||||||
 | 
					    presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(),
 | 
				
			||||||
 | 
					    block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit>
 | 
				
			||||||
 | 
					): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder(
 | 
				
			||||||
 | 
					    BehaviourContext(
 | 
				
			||||||
 | 
					        this,
 | 
				
			||||||
 | 
					        scope.let {
 | 
				
			||||||
 | 
					            if (defaultExceptionsHandler == null) {
 | 
				
			||||||
 | 
					                it
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                it + ContextSafelyExceptionHandler(defaultExceptionsHandler)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        flowUpdatesFilter
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    statesManager,
 | 
				
			||||||
 | 
					    presetHandlers
 | 
				
			||||||
 | 
					).apply { block() }.build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Use this method to build bot behaviour with FSM and run it via long polling. In case you wish to use
 | 
				
			||||||
 | 
					 * [FlowsUpdatesFilter] of result [BehaviourContextWithFSM] for additional manipulations, you must provide external
 | 
				
			||||||
 | 
					 * [FlowsUpdatesFilter] in other [buildBehaviourWithFSM] function.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see buildBehaviourWithFSM
 | 
				
			||||||
 | 
					 * @see BehaviourContext
 | 
				
			||||||
 | 
					 * @see longPolling
 | 
				
			||||||
 | 
					 * @see strictlyOn
 | 
				
			||||||
 | 
					 * @see onStateOrSubstate
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@PreviewFeature
 | 
				
			||||||
 | 
					suspend fun TelegramBot.buildBehaviourWithFSM(
 | 
				
			||||||
 | 
					    scope: CoroutineScope = defaultCoroutineScopeProvider(),
 | 
				
			||||||
 | 
					    defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
 | 
				
			||||||
 | 
					    statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
 | 
				
			||||||
 | 
					    presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(),
 | 
				
			||||||
 | 
					    block: BehaviourContextReceiver<Unit>
 | 
				
			||||||
 | 
					) = FlowsUpdatesFilter().let {
 | 
				
			||||||
 | 
					    buildBehaviourWithFSM(
 | 
				
			||||||
 | 
					        it,
 | 
				
			||||||
 | 
					        scope,
 | 
				
			||||||
 | 
					        defaultExceptionsHandler,
 | 
				
			||||||
 | 
					        statesManager,
 | 
				
			||||||
 | 
					        presetHandlers,
 | 
				
			||||||
 | 
					        block
 | 
				
			||||||
 | 
					    ).run {
 | 
				
			||||||
 | 
					        start()
 | 
				
			||||||
 | 
					        longPolling(
 | 
				
			||||||
 | 
					            flowsUpdatesFilter,
 | 
				
			||||||
 | 
					            scope = scope
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					package dev.inmo.tgbotapi.extensions.behaviour_builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.inmo.micro_utils.coroutines.ExceptionHandler
 | 
				
			||||||
 | 
					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.tgbotapi.bot.Ktor.KtorRequestsExecutorBuilder
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.bot.Ktor.telegramBot
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.bot.TelegramBot
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
 | 
				
			||||||
 | 
					import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
 | 
				
			||||||
 | 
					import kotlinx.coroutines.CoroutineScope
 | 
				
			||||||
 | 
					import kotlinx.coroutines.Job
 | 
				
			||||||
 | 
					import kotlin.coroutines.coroutineContext
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Create bot using [telegramBot] and start listening for updates using [buildBehaviour].
 | 
				
			||||||
 | 
					 * Use this method in case you wish to make some additional actions with [flowsUpdatesFilter].
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * **WARNING** This method WILL NOT launch any listening of updates. Use something like
 | 
				
			||||||
 | 
					 * [startGettingOfUpdatesByLongPolling] or tools for work with webhooks
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return Created bot which has been used to create [BehaviourContext] via [buildBehaviour]
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see [BehaviourContext]
 | 
				
			||||||
 | 
					 * @see [buildBehaviour]
 | 
				
			||||||
 | 
					 * @see startGettingOfUpdatesByLongPolling
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					suspend fun telegramBotWithBehaviourAndFSM(
 | 
				
			||||||
 | 
					    token: String,
 | 
				
			||||||
 | 
					    flowsUpdatesFilter: FlowsUpdatesFilter,
 | 
				
			||||||
 | 
					    scope: CoroutineScope? = null,
 | 
				
			||||||
 | 
					    apiUrl: String = telegramBotAPIDefaultUrl,
 | 
				
			||||||
 | 
					    builder: KtorRequestsExecutorBuilder.() -> Unit = {},
 | 
				
			||||||
 | 
					    defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
 | 
				
			||||||
 | 
					    statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
 | 
				
			||||||
 | 
					    presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(),
 | 
				
			||||||
 | 
					    block: BehaviourContextReceiver<Unit>
 | 
				
			||||||
 | 
					): TelegramBot = telegramBot(
 | 
				
			||||||
 | 
					    token,
 | 
				
			||||||
 | 
					    apiUrl,
 | 
				
			||||||
 | 
					    builder
 | 
				
			||||||
 | 
					).apply {
 | 
				
			||||||
 | 
					    buildBehaviourWithFSM(
 | 
				
			||||||
 | 
					        flowsUpdatesFilter,
 | 
				
			||||||
 | 
					        scope ?: CoroutineScope(coroutineContext),
 | 
				
			||||||
 | 
					        defaultExceptionsHandler,
 | 
				
			||||||
 | 
					        statesManager,
 | 
				
			||||||
 | 
					        presetHandlers,
 | 
				
			||||||
 | 
					        block
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Create bot using [telegramBot] and start listening for updates using [buildBehaviour].
 | 
				
			||||||
 | 
					 * Use this method in case you wish to make some additional actions with [flowsUpdatesFilter].
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * **WARNING** This method WILL NOT launch any listening of updates. Use something like
 | 
				
			||||||
 | 
					 * [startGettingOfUpdatesByLongPolling] or tools for work with webhooks
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return Pair of [TelegramBot] and [Job]. This [Job] can be used to stop listening updates in your [block] you passed
 | 
				
			||||||
 | 
					 * here
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see [BehaviourContext]
 | 
				
			||||||
 | 
					 * @see [buildBehaviour]
 | 
				
			||||||
 | 
					 * @see startGettingOfUpdatesByLongPolling
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					suspend fun telegramBotWithBehaviourAndFSM(
 | 
				
			||||||
 | 
					    token: String,
 | 
				
			||||||
 | 
					    scope: CoroutineScope? = null,
 | 
				
			||||||
 | 
					    apiUrl: String = telegramBotAPIDefaultUrl,
 | 
				
			||||||
 | 
					    builder: KtorRequestsExecutorBuilder.() -> Unit = {},
 | 
				
			||||||
 | 
					    defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
 | 
				
			||||||
 | 
					    statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
 | 
				
			||||||
 | 
					    presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(),
 | 
				
			||||||
 | 
					    block: BehaviourContextReceiver<Unit>
 | 
				
			||||||
 | 
					): Pair<TelegramBot, Job> {
 | 
				
			||||||
 | 
					    return telegramBot(
 | 
				
			||||||
 | 
					        token,
 | 
				
			||||||
 | 
					        apiUrl,
 | 
				
			||||||
 | 
					        builder
 | 
				
			||||||
 | 
					    ).let {
 | 
				
			||||||
 | 
					        it to it.buildBehaviourWithFSM (
 | 
				
			||||||
 | 
					            scope ?: CoroutineScope(coroutineContext),
 | 
				
			||||||
 | 
					            defaultExceptionsHandler,
 | 
				
			||||||
 | 
					            statesManager,
 | 
				
			||||||
 | 
					            presetHandlers,
 | 
				
			||||||
 | 
					            block
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user