mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-12-04 13:26:57 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c3607d817 | |||
| d0add888c4 | |||
| 3e3adab46b | |||
| 89d13de307 | |||
| 32451f4e1c | |||
| ad50f41d1e | |||
| 8c9cd9df67 | |||
| 8e7f7a03c8 | |||
| 484e09374d | |||
|
|
619c82bb32 | ||
| 33fb75a5eb | |||
| a52f31f4c9 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 0.38.19
|
||||
|
||||
* `BehaviourBuilder`:
|
||||
* Hotfixes
|
||||
* `BehaviourBuilder FSM`:
|
||||
* `BehaviourContextWithFSMBuilder` deprecated in favor to `BehaviourContextWithFSM`
|
||||
* Now it is possible to define additional handlers in subcontexts of `BehaviourBuilderWithFSM`
|
||||
|
||||
## 0.38.18
|
||||
|
||||
* `Core`:
|
||||
* Add support of test servers (fix of [#577](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/577))
|
||||
* `BehaviourBuilder`:
|
||||
* Fixes in extension `BehaviourContext#doInSubContextWithUpdatesFilter` (thanks to [xzima](https://github.com/xzima))
|
||||
|
||||
## 0.38.17
|
||||
|
||||
* `Core`:
|
||||
|
||||
@@ -20,6 +20,6 @@ javax_activation_version=1.1.1
|
||||
dokka_version=1.6.10
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=0.38.17
|
||||
library_version=0.38.19
|
||||
|
||||
github_release_plugin_version=2.3.7
|
||||
|
||||
@@ -40,8 +40,9 @@ data class BotBuilder internal constructor(
|
||||
fun buildBot(
|
||||
token: String,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
testServer: Boolean = false,
|
||||
block: BotBuilder.() -> Unit
|
||||
) = telegramBot(
|
||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||
BotBuilder().apply(block).createHttpClient()
|
||||
)
|
||||
|
||||
@@ -66,17 +66,19 @@ inline fun telegramBot(
|
||||
inline fun telegramBot(
|
||||
token: String,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
testServer: Boolean = false,
|
||||
client: HttpClient = HttpClient()
|
||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client)
|
||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, testServer, apiUrl), client)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T: HttpClientEngineConfig> telegramBot(
|
||||
token: String,
|
||||
clientFactory: HttpClientEngineFactory<T>,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
testServer: Boolean = false,
|
||||
noinline clientConfig: HttpClientConfig<T>.() -> Unit = {}
|
||||
) = telegramBot(
|
||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||
clientFactory,
|
||||
clientConfig
|
||||
)
|
||||
@@ -90,9 +92,10 @@ inline fun telegramBot(
|
||||
token: String,
|
||||
clientEngine: HttpClientEngine,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
testServer: Boolean = false,
|
||||
noinline clientConfig: HttpClientConfig<*>.() -> Unit = {}
|
||||
) = telegramBot(
|
||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||
clientEngine,
|
||||
clientConfig
|
||||
)
|
||||
@@ -105,8 +108,9 @@ inline fun telegramBot(
|
||||
inline fun telegramBot(
|
||||
token: String,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
testServer: Boolean = false,
|
||||
noinline clientConfig: HttpClientConfig<*>.() -> Unit
|
||||
) = telegramBot(
|
||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
||||
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||
clientConfig
|
||||
)
|
||||
|
||||
@@ -9,6 +9,8 @@ import dev.inmo.micro_utils.coroutines.accumulatorFlow
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have
|
||||
@@ -30,6 +32,25 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see onStateOrSubstate
|
||||
*/
|
||||
fun <I : T> add(kClass: KClass<I>, strict: Boolean = false, handler: BehaviourWithFSMStateHandler<I, T>)
|
||||
|
||||
/**
|
||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||
* requirements
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see strictlyOn
|
||||
*/
|
||||
fun <I : T> addStrict(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) = add(kClass, strict = true, handler)
|
||||
|
||||
override fun copy(
|
||||
bot: TelegramBot,
|
||||
scope: CoroutineScope,
|
||||
@@ -48,6 +69,28 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see BehaviourContextWithFSM.add
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inline fun <reified I : O, O: State> BehaviourContextWithFSM<O>.onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, O>) = add(I::class, strict = false, handler)
|
||||
|
||||
/**
|
||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||
* requirements
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see BehaviourContextWithFSM.addStrict
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inline fun <reified I : O, O: State> BehaviourContextWithFSM<O>.strictlyOn(handler: BehaviourWithFSMStateHandler<I, O>) = addStrict(I::class, handler)
|
||||
|
||||
/**
|
||||
* Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as
|
||||
* [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states
|
||||
@@ -58,6 +101,9 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
private val handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
|
||||
) : BehaviourContext by behaviourContext, BehaviourContextWithFSM<T> {
|
||||
private val updatesFlows = mutableMapOf<Any, Flow<Update>>()
|
||||
private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>()
|
||||
private var actualHandlersList = additionalHandlers + handlers
|
||||
|
||||
private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) {
|
||||
allUpdatesFlow.accumulatorFlow(scope)
|
||||
}
|
||||
@@ -65,12 +111,17 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
override suspend fun StatesMachine<in T>.handleState(state: T): T? = launchStateHandling(
|
||||
state,
|
||||
allUpdatesFlow,
|
||||
handlers
|
||||
actualHandlersList
|
||||
)
|
||||
|
||||
override fun <I : T> add(kClass: KClass<I>, strict: Boolean, handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||
additionalHandlers.add(BehaviourWithFSMStateHandlerHolder(kClass, strict, handler))
|
||||
actualHandlersList = additionalHandlers + handlers
|
||||
}
|
||||
|
||||
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
|
||||
val statePerformer: suspend (T) -> Unit = { state: T ->
|
||||
val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers)
|
||||
val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), actualHandlersList)
|
||||
if (newState != null) {
|
||||
statesManager.update(state, newState)
|
||||
} else {
|
||||
@@ -94,6 +145,26 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
launch { statePerformer(it) }
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see BehaviourContextWithFSM.add
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inline fun <reified I : T> onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, T>) = add(I::class, strict = false, handler)
|
||||
|
||||
/**
|
||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||
* requirements
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see BehaviourContextWithFSM.addStrict
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inline fun <reified I : T> strictlyOn(handler: BehaviourWithFSMStateHandler<I, T>) = addStrict(I::class, handler)
|
||||
|
||||
override suspend fun startChain(state: T) {
|
||||
statesManager.startChain(state)
|
||||
@@ -106,7 +177,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
onBufferOverflow: BufferOverflow,
|
||||
upstreamUpdatesFlow: Flow<Update>?,
|
||||
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
||||
): BehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
||||
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
||||
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter),
|
||||
handlers,
|
||||
statesManager
|
||||
|
||||
@@ -14,70 +14,8 @@ import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class BehaviourContextWithFSMBuilder<T : State> internal constructor(
|
||||
private val resultBehaviourContext: BehaviourContextWithFSM<T>,
|
||||
private val handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>>
|
||||
) : BehaviourContextWithFSM<T> by resultBehaviourContext {
|
||||
internal constructor(
|
||||
baseBehaviourContext: BehaviourContext,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf()
|
||||
) : this(DefaultBehaviourContextWithFSM(baseBehaviourContext, statesManager, handlers), handlers)
|
||||
|
||||
/**
|
||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see onStateOrSubstate
|
||||
*/
|
||||
fun <I : T> add(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, false, handler))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||
* requirements
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see strictlyOn
|
||||
*/
|
||||
fun <I : T> addStrict(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, true, handler))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
|
||||
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see BehaviourContextWithFSMBuilder.add
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inline fun <reified I : T> onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||
add(I::class, handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
|
||||
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass
|
||||
* requirements
|
||||
*
|
||||
* @see BehaviourWithFSMStateHandlerHolder
|
||||
* @see BehaviourContextWithFSMBuilder.addStrict
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inline fun <reified I : T> strictlyOn(handler: BehaviourWithFSMStateHandler<I, T>) {
|
||||
addStrict(I::class, handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns completed [resultBehaviourContext], [handlers] and [statesManager]
|
||||
*/
|
||||
internal fun build() = resultBehaviourContext
|
||||
}
|
||||
@Deprecated("Will be removed soon")
|
||||
typealias BehaviourContextWithFSMBuilder<T> = BehaviourContextWithFSM<T>
|
||||
|
||||
/**
|
||||
* Creates [BehaviourContextWithFSM] via creating of [DefaultBehaviourContext] with [this] as [TelegramBot],
|
||||
@@ -94,17 +32,17 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||
): BehaviourContextWithFSM<T> = BehaviourContextWithFSMBuilder(
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
||||
DefaultBehaviourContext(
|
||||
this,
|
||||
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
|
||||
upstreamUpdatesFlow = upstreamUpdatesFlow
|
||||
),
|
||||
statesManager,
|
||||
presetHandlers
|
||||
).apply { block() }.build()
|
||||
presetHandlers,
|
||||
statesManager
|
||||
).apply { block() }
|
||||
|
||||
/**
|
||||
* Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates
|
||||
@@ -116,9 +54,9 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||
): Pair<BehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
||||
upstreamUpdatesFlow,
|
||||
scope,
|
||||
defaultExceptionsHandler,
|
||||
@@ -147,8 +85,8 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||
* @see BehaviourContext
|
||||
* @see BehaviourContextWithFSM
|
||||
* @see longPolling
|
||||
* @see BehaviourContextWithFSMBuilder.strictlyOn
|
||||
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate
|
||||
* @see BehaviourContextWithFSM.strictlyOn
|
||||
* @see BehaviourContextWithFSM.onStateOrSubstate
|
||||
*/
|
||||
@PreviewFeature
|
||||
suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
||||
@@ -156,17 +94,17 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||
): BehaviourContextWithFSM<T> = BehaviourContextWithFSMBuilder(
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
|
||||
DefaultBehaviourContext(
|
||||
this,
|
||||
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
|
||||
upstreamUpdatesFlow = flowUpdatesFilter.allUpdatesFlow
|
||||
),
|
||||
statesManager,
|
||||
presetHandlers
|
||||
).apply { block() }.build()
|
||||
presetHandlers,
|
||||
statesManager
|
||||
).apply { block() }
|
||||
|
||||
/**
|
||||
* Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates
|
||||
@@ -176,16 +114,16 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
|
||||
* @see buildBehaviourWithFSMAndStartLongPolling
|
||||
* @see BehaviourContext
|
||||
* @see longPolling
|
||||
* @see BehaviourContextWithFSMBuilder.strictlyOn
|
||||
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate
|
||||
* @see BehaviourContextWithFSM.strictlyOn
|
||||
* @see BehaviourContextWithFSM.onStateOrSubstate
|
||||
*/
|
||||
@PreviewFeature
|
||||
suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
) = FlowsUpdatesFilter().let {
|
||||
buildBehaviourWithFSM(
|
||||
it,
|
||||
|
||||
@@ -37,11 +37,13 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
testServer: Boolean = false,
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): TelegramBot = telegramBot(
|
||||
token,
|
||||
apiUrl,
|
||||
testServer,
|
||||
builder
|
||||
).apply {
|
||||
buildBehaviourWithFSMAndStartLongPolling(
|
||||
@@ -72,12 +74,14 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||
testServer: Boolean = false,
|
||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||
): Pair<TelegramBot, Job> {
|
||||
return telegramBot(
|
||||
token,
|
||||
apiUrl,
|
||||
testServer,
|
||||
builder
|
||||
).let {
|
||||
it to it.buildBehaviourWithFSMAndStartLongPolling (
|
||||
|
||||
@@ -90,7 +90,7 @@ class DefaultBehaviourContext(
|
||||
onBufferOverflow: BufferOverflow,
|
||||
upstreamUpdatesFlow: Flow<Update>?,
|
||||
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
||||
): BehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter)
|
||||
): DefaultBehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter)
|
||||
}
|
||||
|
||||
fun BehaviourContext(
|
||||
@@ -116,19 +116,20 @@ suspend fun <T, BC : BehaviourContext> BC.doInSubContextWithUpdatesFilter(
|
||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
||||
scope: CoroutineScope = LinkedSupervisorScope(),
|
||||
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
||||
): T = copy(
|
||||
scope = scope,
|
||||
updatesFilter = updatesFilter ?.let { _ ->
|
||||
{
|
||||
(this as? BC) ?.run {
|
||||
updatesFilter(it)
|
||||
} ?: true
|
||||
}
|
||||
},
|
||||
upstreamUpdatesFlow = updatesUpstreamFlow
|
||||
).run {
|
||||
withContext(coroutineContext) {
|
||||
behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
||||
): T {
|
||||
val newContext = copy(
|
||||
scope = scope,
|
||||
updatesFilter = updatesFilter ?.let { _ ->
|
||||
{
|
||||
(this as? BC) ?.run {
|
||||
updatesFilter(it)
|
||||
} ?: true
|
||||
}
|
||||
},
|
||||
upstreamUpdatesFlow = updatesUpstreamFlow
|
||||
) as BC
|
||||
return withContext(currentCoroutineContext()) {
|
||||
newContext.behaviourContextReceiver().also { if (stopOnCompletion) newContext.stop() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,12 @@ suspend fun telegramBotWithBehaviour(
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
testServer: Boolean = false,
|
||||
block: BehaviourContextReceiver<Unit>
|
||||
): TelegramBot = telegramBot(
|
||||
token,
|
||||
apiUrl,
|
||||
testServer,
|
||||
builder
|
||||
).apply {
|
||||
buildBehaviour(
|
||||
@@ -63,11 +65,13 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||
testServer: Boolean = false,
|
||||
block: BehaviourContextReceiver<Unit>
|
||||
): Pair<TelegramBot, Job> {
|
||||
return telegramBot(
|
||||
token,
|
||||
apiUrl,
|
||||
testServer,
|
||||
builder
|
||||
).let {
|
||||
it to it.buildBehaviourWithLongPolling(
|
||||
|
||||
@@ -125,5 +125,6 @@ inline fun telegramBot(
|
||||
inline fun telegramBot(
|
||||
token: String,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
testServer: Boolean = false,
|
||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, testServer, apiUrl), builder)
|
||||
|
||||
@@ -16,7 +16,8 @@ private inline val String.withoutLastSlash: String
|
||||
|
||||
class TelegramAPIUrlsKeeper(
|
||||
token: String,
|
||||
hostUrl: String = telegramBotAPIDefaultUrl
|
||||
hostUrl: String = telegramBotAPIDefaultUrl,
|
||||
urlsSuffixes: String = ""
|
||||
) {
|
||||
val webAppDataSecretKey by lazy {
|
||||
token.hmacSha256("WebAppData")
|
||||
@@ -25,10 +26,16 @@ class TelegramAPIUrlsKeeper(
|
||||
val commonAPIUrl: String
|
||||
val fileBaseUrl: String
|
||||
|
||||
constructor(token: String, testServer: Boolean, hostUrl: String = telegramBotAPIDefaultUrl) : this(
|
||||
token,
|
||||
hostUrl,
|
||||
"/test".takeIf { testServer } ?: ""
|
||||
)
|
||||
|
||||
init {
|
||||
val correctedHost = hostUrl.withoutLastSlash
|
||||
commonAPIUrl = "$correctedHost/bot$token"
|
||||
fileBaseUrl = "$correctedHost/file/bot$token"
|
||||
commonAPIUrl = "$correctedHost/bot$token$urlsSuffixes"
|
||||
fileBaseUrl = "$correctedHost/file/bot$token$urlsSuffixes"
|
||||
}
|
||||
|
||||
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
||||
|
||||
Reference in New Issue
Block a user