mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 16:23:48 +00:00
improving work of behaviour_builder
This commit is contained in:
parent
30a4a7bd8b
commit
fc71e028c4
11
CHANGELOG.md
11
CHANGELOG.md
@ -8,8 +8,17 @@
|
|||||||
* `Version`:
|
* `Version`:
|
||||||
* `MicroUtils`: `0.4.16` -> `0.4.19`
|
* `MicroUtils`: `0.4.16` -> `0.4.19`
|
||||||
* `Core`:
|
* `Core`:
|
||||||
* **BC** Now `MediaGroupMessage` have a generic type related to `MediaGroupContent`
|
* **BREAKING CHANGE** Now `MediaGroupMessage` have a generic type related to `MediaGroupContent`
|
||||||
* Methods and types related to `MediaGroupMessage` have been modified according to their meanings
|
* Methods and types related to `MediaGroupMessage` have been modified according to their meanings
|
||||||
|
* **Important Change** `FlowsUpdatesFilter` now is an interface. Old class has been renamed to
|
||||||
|
`DefaultFlowsUpdatesFilter` and factory method `FlowsUpdatesFilter` has been added
|
||||||
|
* `Behaviour Builder`:
|
||||||
|
* Trigger and expectation extensions for `MessageContent` (`onContentMessage` and `waitContentMessage`)
|
||||||
|
* `onMediaGroup` has been replaced
|
||||||
|
* `waitMediaGroup` has been added
|
||||||
|
* `onVisualMediaGroup` now is just an alternative to `onVisualGallery`
|
||||||
|
* `command` and `onCommand` expectations has been added for commands `String` variant
|
||||||
|
* New extensions `BehaviourContext#oneOf`, `BehaviourContext#parallel` and `Deferred<T>#withAction`
|
||||||
|
|
||||||
## 0.31.0
|
## 0.31.0
|
||||||
|
|
||||||
|
@ -7,15 +7,47 @@ import dev.inmo.tgbotapi.types.update.abstracts.UnknownUpdate
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
@Suppress("EXPERIMENTAL_API_USAGE", "unused")
|
interface FlowsUpdatesFilter : UpdatesFilter {
|
||||||
class FlowsUpdatesFilter(
|
override val allowedUpdates: List<String>
|
||||||
|
get() = ALL_UPDATES_LIST
|
||||||
|
val allUpdatesFlow: Flow<Update>
|
||||||
|
val allUpdatesWithoutMediaGroupsGroupingFlow: Flow<Update>
|
||||||
|
|
||||||
|
val messageFlow: Flow<MessageUpdate>
|
||||||
|
val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate>
|
||||||
|
val editedMessageFlow: Flow<EditMessageUpdate>
|
||||||
|
val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate>
|
||||||
|
val channelPostFlow: Flow<ChannelPostUpdate>
|
||||||
|
val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate>
|
||||||
|
val editedChannelPostFlow: Flow<EditChannelPostUpdate>
|
||||||
|
val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate>
|
||||||
|
val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate>
|
||||||
|
val inlineQueryFlow: Flow<InlineQueryUpdate>
|
||||||
|
val callbackQueryFlow: Flow<CallbackQueryUpdate>
|
||||||
|
val shippingQueryFlow: Flow<ShippingQueryUpdate>
|
||||||
|
val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate>
|
||||||
|
val pollFlow: Flow<PollUpdate>
|
||||||
|
val pollAnswerFlow: Flow<PollAnswerUpdate>
|
||||||
|
val unknownUpdateTypeFlow: Flow<UnknownUpdate>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [DefaultFlowsUpdatesFilter]
|
||||||
|
*/
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
fun FlowsUpdatesFilter(
|
||||||
broadcastChannelsSize: Int = 100
|
broadcastChannelsSize: Int = 100
|
||||||
): UpdatesFilter {
|
) = DefaultFlowsUpdatesFilter(broadcastChannelsSize)
|
||||||
|
|
||||||
|
@Suppress("EXPERIMENTAL_API_USAGE", "unused")
|
||||||
|
class DefaultFlowsUpdatesFilter(
|
||||||
|
broadcastChannelsSize: Int = 100
|
||||||
|
): FlowsUpdatesFilter {
|
||||||
private val updatesSharedFlow = MutableSharedFlow<Update>(extraBufferCapacity = broadcastChannelsSize)
|
private val updatesSharedFlow = MutableSharedFlow<Update>(extraBufferCapacity = broadcastChannelsSize)
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
val allUpdatesFlow: Flow<Update> = updatesSharedFlow.asSharedFlow()
|
override val allUpdatesFlow: Flow<Update> = updatesSharedFlow.asSharedFlow()
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
val allUpdatesWithoutMediaGroupsGroupingFlow: Flow<Update> = updatesSharedFlow.flatMapConcat {
|
override val allUpdatesWithoutMediaGroupsGroupingFlow: Flow<Update> = allUpdatesFlow.flatMapConcat {
|
||||||
when (it) {
|
when (it) {
|
||||||
is SentMediaGroupUpdate -> it.origins.asFlow()
|
is SentMediaGroupUpdate -> it.origins.asFlow()
|
||||||
is EditMediaGroupUpdate -> flowOf(it.origin)
|
is EditMediaGroupUpdate -> flowOf(it.origin)
|
||||||
@ -23,26 +55,24 @@ class FlowsUpdatesFilter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val allowedUpdates: List<String>
|
|
||||||
get() = ALL_UPDATES_LIST
|
|
||||||
override val asUpdateReceiver: UpdateReceiver<Update> = {
|
override val asUpdateReceiver: UpdateReceiver<Update> = {
|
||||||
updatesSharedFlow.emit(it)
|
updatesSharedFlow.emit(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val messageFlow: Flow<MessageUpdate> = allUpdatesFlow.filterIsInstance()
|
override val messageFlow: Flow<MessageUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
override val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val editedMessageFlow: Flow<EditMessageUpdate> = allUpdatesFlow.filterIsInstance()
|
override val editedMessageFlow: Flow<EditMessageUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
override val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val channelPostFlow: Flow<ChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
|
override val channelPostFlow: Flow<ChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
override val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val editedChannelPostFlow: Flow<EditChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
|
override val editedChannelPostFlow: Flow<EditChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
override val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate> = allUpdatesFlow.filterIsInstance()
|
override val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val inlineQueryFlow: Flow<InlineQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
override val inlineQueryFlow: Flow<InlineQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val callbackQueryFlow: Flow<CallbackQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
override val callbackQueryFlow: Flow<CallbackQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val shippingQueryFlow: Flow<ShippingQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
override val shippingQueryFlow: Flow<ShippingQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
override val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val pollFlow: Flow<PollUpdate> = allUpdatesFlow.filterIsInstance()
|
override val pollFlow: Flow<PollUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val pollAnswerFlow: Flow<PollAnswerUpdate> = allUpdatesFlow.filterIsInstance()
|
override val pollAnswerFlow: Flow<PollAnswerUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
val unknownUpdateTypeFlow: Flow<UnknownUpdate> = allUpdatesFlow.filterIsInstance()
|
override val unknownUpdateTypeFlow: Flow<UnknownUpdate> = allUpdatesFlow.filterIsInstance()
|
||||||
}
|
}
|
@ -1,9 +1,11 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder
|
package dev.inmo.tgbotapi.extensions.behaviour_builder
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
import dev.inmo.tgbotapi.updateshandlers.UpdatesFilter
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.flow.filter
|
||||||
|
|
||||||
typealias BehaviourContextReceiver<T> = suspend BehaviourContext.() -> T
|
typealias BehaviourContextReceiver<T> = suspend BehaviourContext.() -> T
|
||||||
typealias BehaviourContextAndTypeReceiver<T, I> = suspend BehaviourContext.(I) -> T
|
typealias BehaviourContextAndTypeReceiver<T, I> = suspend BehaviourContext.(I) -> T
|
||||||
@ -19,4 +21,48 @@ data class BehaviourContext(
|
|||||||
val bot: TelegramBot,
|
val bot: TelegramBot,
|
||||||
val scope: CoroutineScope,
|
val scope: CoroutineScope,
|
||||||
val flowsUpdatesFilter: FlowsUpdatesFilter = FlowsUpdatesFilter()
|
val flowsUpdatesFilter: FlowsUpdatesFilter = FlowsUpdatesFilter()
|
||||||
) : UpdatesFilter by flowsUpdatesFilter, TelegramBot by bot, CoroutineScope by scope
|
) : FlowsUpdatesFilter by flowsUpdatesFilter, TelegramBot by bot, CoroutineScope by scope
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [newFlowsUpdatesFilterSetUp] is provided and
|
||||||
|
* [CoroutineScope] as new [BehaviourContext.scope]
|
||||||
|
*
|
||||||
|
* @param newFlowsUpdatesFilterSetUp As a parameter receives [FlowsUpdatesFilter] from old [this] [BehaviourContext.flowsUpdatesFilter]
|
||||||
|
*/
|
||||||
|
suspend fun <T> BehaviourContext.doInSubContextWithFlowsUpdatesFilterSetup(
|
||||||
|
newFlowsUpdatesFilterSetUp: BehaviourContextAndTypeReceiver<Unit, FlowsUpdatesFilter>?,
|
||||||
|
behaviourContextReceiver: BehaviourContextReceiver<T>
|
||||||
|
) = copy(
|
||||||
|
flowsUpdatesFilter = FlowsUpdatesFilter(),
|
||||||
|
scope = CoroutineScope(scope.coroutineContext + SupervisorJob())
|
||||||
|
).run {
|
||||||
|
newFlowsUpdatesFilterSetUp ?.let {
|
||||||
|
it.apply { invoke(this@run, this@doInSubContextWithFlowsUpdatesFilterSetup.flowsUpdatesFilter) }
|
||||||
|
}
|
||||||
|
behaviourContextReceiver().also { stop() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [updatesFilter] is provided and
|
||||||
|
* [CoroutineScope] as new [BehaviourContext.scope]
|
||||||
|
*/
|
||||||
|
suspend fun <T> BehaviourContext.doInSubContextWithUpdatesFilter(
|
||||||
|
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?,
|
||||||
|
behaviourContextReceiver: BehaviourContextReceiver<T>
|
||||||
|
) = doInSubContextWithFlowsUpdatesFilterSetup(
|
||||||
|
newFlowsUpdatesFilterSetUp = updatesFilter ?.let {
|
||||||
|
{ oldOne ->
|
||||||
|
oldOne.allUpdatesFlow.filter { updatesFilter(it) }.subscribeSafelyWithoutExceptions(scope, asUpdateReceiver)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
behaviourContextReceiver
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun <T> BehaviourContext.doInSubContext(
|
||||||
|
behaviourContextReceiver: BehaviourContextReceiver<T>
|
||||||
|
) = doInSubContextWithFlowsUpdatesFilterSetup(newFlowsUpdatesFilterSetUp = null, behaviourContextReceiver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will cancel ALL subsequent contexts, expectations and waiters
|
||||||
|
*/
|
||||||
|
fun BehaviourContext.stop() = scope.cancel()
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.behaviour_builder
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.DeferredAction
|
||||||
|
import dev.inmo.micro_utils.coroutines.invokeFirstOf
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
|
suspend fun <T> BehaviourContext.parallel(
|
||||||
|
action: BehaviourContextReceiver<T>
|
||||||
|
) = async {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline infix fun <T, O> Deferred<T>.withAction(noinline callback: suspend (T) -> O) = DeferredAction(this, callback)
|
||||||
|
|
||||||
|
suspend fun <O> BehaviourContext.oneOf(
|
||||||
|
deferredActions: Iterable<DeferredAction<*, O>>
|
||||||
|
) = deferredActions.invokeFirstOf(scope)
|
||||||
|
|
||||||
|
suspend fun <O> BehaviourContext.oneOf(
|
||||||
|
vararg deferredActions: DeferredAction<*, O>
|
||||||
|
) = oneOf(deferredActions.toList())
|
@ -59,6 +59,12 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: CommonMessageToContentMapper<MessageContent>? = null
|
||||||
|
) = waitContent(count, initRequest, false, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitContact(
|
suspend fun BehaviourContext.waitContact(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
@ -101,14 +107,14 @@ suspend fun BehaviourContext.waitVenue(
|
|||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: CommonMessageToContentMapper<VenueContent>? = null
|
filter: CommonMessageToContentMapper<VenueContent>? = null
|
||||||
) = waitContent(count, initRequest, false, errorFactory, filter)
|
) = waitContent(count, initRequest, false, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitAudioMediaGroup(
|
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
filter: CommonMessageToContentMapper<AudioMediaGroupContent>? = null
|
filter: CommonMessageToContentMapper<AudioMediaGroupContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitDocumentMediaGroup(
|
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
@ -119,17 +125,17 @@ suspend fun BehaviourContext.waitMedia(
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
filter: CommonMessageToContentMapper<MediaContent>? = null
|
filter: CommonMessageToContentMapper<MediaContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitMediaGroup(
|
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
filter: CommonMessageToContentMapper<MediaGroupContent>? = null
|
filter: CommonMessageToContentMapper<MediaGroupContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitVisualMediaGroup(
|
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
@ -146,21 +152,21 @@ suspend fun BehaviourContext.waitAudio(
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
filter: CommonMessageToContentMapper<AudioContent>? = null
|
filter: CommonMessageToContentMapper<AudioContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitDocument(
|
suspend fun BehaviourContext.waitDocument(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
filter: CommonMessageToContentMapper<DocumentContent>? = null
|
filter: CommonMessageToContentMapper<DocumentContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitPhoto(
|
suspend fun BehaviourContext.waitPhoto(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
filter: CommonMessageToContentMapper<PhotoContent>? = null
|
filter: CommonMessageToContentMapper<PhotoContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitSticker(
|
suspend fun BehaviourContext.waitSticker(
|
||||||
@ -173,7 +179,7 @@ suspend fun BehaviourContext.waitVideo(
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
filter: CommonMessageToContentMapper<VideoContent>? = null
|
filter: CommonMessageToContentMapper<VideoContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitVideoNote(
|
suspend fun BehaviourContext.waitVideoNote(
|
||||||
|
@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.take
|
|||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
|
|
||||||
@PreviewFeature
|
@PreviewFeature
|
||||||
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup(
|
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.buildMediaGroupWaiter(
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
@ -21,7 +21,7 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
|
|||||||
update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
|
update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
|
||||||
if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup as List<MediaGroupMessage<T>>))) {
|
if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup as List<MediaGroupMessage<T>>))) {
|
||||||
listOf(
|
listOf(
|
||||||
mediaGroup.map { it.content as T } as List<MediaGroupMessage<T>>
|
mediaGroup.map { it.content as T }
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@ -29,33 +29,39 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
|
|||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
}.take(count).toList()
|
}.take(count).toList()
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitMediaGroup(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: (suspend (List<MediaGroupMessage<MediaGroupContent>>) -> Boolean)? = null
|
||||||
|
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitPlaylist(
|
suspend fun BehaviourContext.waitPlaylist(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null
|
filter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null
|
||||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitDocumentsGroup(
|
suspend fun BehaviourContext.waitDocumentsGroup(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null
|
filter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null
|
||||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitVisualGallery(
|
suspend fun BehaviourContext.waitVisualGallery(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null
|
filter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null
|
||||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitPhotoGallery(
|
suspend fun BehaviourContext.waitPhotoGallery(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null
|
filter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null
|
||||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||||
suspend fun BehaviourContext.waitVideoGallery(
|
suspend fun BehaviourContext.waitVideoGallery(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null
|
filter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null
|
||||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||||
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||||
import dev.inmo.tgbotapi.extensions.utils.*
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
||||||
import dev.inmo.tgbotapi.types.CallbackQuery.*
|
import dev.inmo.tgbotapi.types.CallbackQuery.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
|
||||||
import kotlinx.coroutines.flow.filter
|
|
||||||
|
|
||||||
internal suspend inline fun <reified T : CallbackQuery> BehaviourContext.onCallbackQuery(
|
internal suspend inline fun <reified T : CallbackQuery> BehaviourContext.onCallbackQuery(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
@ -27,19 +21,15 @@ internal suspend inline fun <reified T : CallbackQuery> BehaviourContext.onCallb
|
|||||||
}
|
}
|
||||||
}.let(::listOfNotNull)
|
}.let(::listOfNotNull)
|
||||||
}.subscribeSafelyWithoutExceptions(scope) { triggerQuery ->
|
}.subscribeSafelyWithoutExceptions(scope) { triggerQuery ->
|
||||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
doInSubContextWithUpdatesFilter(
|
||||||
val subFilter = FlowsUpdatesFilter()
|
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
{ it.sourceChat() ?.id ?.chatId == triggerQuery.user.id.chatId }
|
||||||
|
} else {
|
||||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
null
|
||||||
val chat = it.sourceChat() ?: return@filter false
|
}
|
||||||
chat.id.chatId == triggerQuery.user.id.chatId
|
) {
|
||||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
scenarioReceiver(triggerQuery)
|
||||||
} else {
|
|
||||||
null to this
|
|
||||||
}
|
}
|
||||||
safelyWithoutExceptions { scenario.scenarioReceiver(triggerQuery) }
|
|
||||||
jobToCancel ?.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,12 @@ suspend fun BehaviourContext.command(
|
|||||||
},
|
},
|
||||||
scenarioReceiver
|
scenarioReceiver
|
||||||
)
|
)
|
||||||
|
suspend fun BehaviourContext.command(
|
||||||
|
command: String,
|
||||||
|
requireOnlyCommandInMessage: Boolean = true,
|
||||||
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
|
||||||
|
) = command(command.toRegex(), requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, scenarioReceiver)
|
||||||
|
|
||||||
suspend inline fun BehaviourContext.onCommand(
|
suspend inline fun BehaviourContext.onCommand(
|
||||||
commandRegex: Regex,
|
commandRegex: Regex,
|
||||||
@ -33,3 +39,10 @@ suspend inline fun BehaviourContext.onCommand(
|
|||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
|
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
|
||||||
): Job = command(commandRegex, requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, scenarioReceiver)
|
): Job = command(commandRegex, requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, scenarioReceiver)
|
||||||
|
|
||||||
|
suspend inline fun BehaviourContext.onCommand(
|
||||||
|
command: String,
|
||||||
|
requireOnlyCommandInMessage: Boolean = true,
|
||||||
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
|
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
|
||||||
|
): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, scenarioReceiver)
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
|
|
||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||||
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||||
import dev.inmo.tgbotapi.extensions.utils.*
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
||||||
@ -16,9 +13,7 @@ import dev.inmo.tgbotapi.types.message.content.*
|
|||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
|
||||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||||
import kotlinx.coroutines.flow.filter
|
|
||||||
|
|
||||||
typealias CommonMessageFilter<T> = (suspend (CommonMessage<T>) -> Boolean)
|
typealias CommonMessageFilter<T> = (suspend (CommonMessage<T>) -> Boolean)
|
||||||
|
|
||||||
@ -50,21 +45,22 @@ internal suspend inline fun <reified T : MessageContent> BehaviourContext.onCont
|
|||||||
}
|
}
|
||||||
}.let(::listOfNotNull)
|
}.let(::listOfNotNull)
|
||||||
}.subscribeSafelyWithoutExceptions(scope) { triggerMessage ->
|
}.subscribeSafelyWithoutExceptions(scope) { triggerMessage ->
|
||||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
doInSubContextWithUpdatesFilter(
|
||||||
val subFilter = FlowsUpdatesFilter()
|
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||||
|
} else {
|
||||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
null
|
||||||
val chat = it.sourceChat() ?: return@filter false
|
}
|
||||||
chat.id.chatId == triggerMessage.chat.id.chatId
|
) {
|
||||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
scenarioReceiver(triggerMessage)
|
||||||
} else {
|
|
||||||
null to this
|
|
||||||
}
|
}
|
||||||
safelyWithoutExceptions { scenario.scenarioReceiver(triggerMessage) }
|
|
||||||
jobToCancel ?.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.onContentMessage(
|
||||||
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
|
additionalFilter: CommonMessageFilter<MessageContent>? = null,
|
||||||
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MessageContent>>
|
||||||
|
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onContact(
|
suspend fun BehaviourContext.onContact(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: CommonMessageFilter<ContactContent>? = null,
|
additionalFilter: CommonMessageFilter<ContactContent>? = null,
|
||||||
@ -105,7 +101,7 @@ suspend fun BehaviourContext.onAudioMediaGroup(
|
|||||||
additionalFilter: CommonMessageFilter<AudioMediaGroupContent>? = null,
|
additionalFilter: CommonMessageFilter<AudioMediaGroupContent>? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioMediaGroupContent>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioMediaGroupContent>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onDocumentMediaGroup(
|
suspend fun BehaviourContext.onDocumentMediaGroupContent(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
additionalFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null,
|
additionalFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null,
|
||||||
@ -113,7 +109,7 @@ suspend fun BehaviourContext.onDocumentMediaGroup(
|
|||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onMediaCollection(
|
suspend fun BehaviourContext.onMediaCollection(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
additionalFilter: (suspend (CommonMessage<MediaCollectionContent<TelegramMediaFile>>) -> Boolean)? = null,
|
additionalFilter: (suspend (CommonMessage<MediaCollectionContent<TelegramMediaFile>>) -> Boolean)? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
@ -123,18 +119,6 @@ suspend fun BehaviourContext.onMedia(
|
|||||||
additionalFilter: CommonMessageFilter<MediaContent>? = null,
|
additionalFilter: CommonMessageFilter<MediaContent>? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaContent>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaContent>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onMediaGroup(
|
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
|
||||||
includeMediaGroups: Boolean = true,
|
|
||||||
additionalFilter: CommonMessageFilter<MediaGroupContent>? = null,
|
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaGroupContent>>
|
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
|
||||||
suspend fun BehaviourContext.onVisualMediaGroup(
|
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
|
||||||
includeMediaGroups: Boolean = true,
|
|
||||||
additionalFilter: CommonMessageFilter<VisualMediaGroupContent>? = null,
|
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VisualMediaGroupContent>>
|
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
|
||||||
suspend fun BehaviourContext.onAnimation(
|
suspend fun BehaviourContext.onAnimation(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: CommonMessageFilter<AnimationContent>? = null,
|
additionalFilter: CommonMessageFilter<AnimationContent>? = null,
|
||||||
@ -142,19 +126,19 @@ suspend fun BehaviourContext.onAnimation(
|
|||||||
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onAudio(
|
suspend fun BehaviourContext.onAudio(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
additionalFilter: CommonMessageFilter<AudioContent>? = null,
|
additionalFilter: CommonMessageFilter<AudioContent>? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioContent>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioContent>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onDocument(
|
suspend fun BehaviourContext.onDocument(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
additionalFilter: CommonMessageFilter<DocumentContent>? = null,
|
additionalFilter: CommonMessageFilter<DocumentContent>? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<DocumentContent>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<DocumentContent>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onPhoto(
|
suspend fun BehaviourContext.onPhoto(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
additionalFilter: CommonMessageFilter<PhotoContent>? = null,
|
additionalFilter: CommonMessageFilter<PhotoContent>? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<PhotoContent>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<PhotoContent>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
@ -165,7 +149,7 @@ suspend fun BehaviourContext.onSticker(
|
|||||||
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onVideo(
|
suspend fun BehaviourContext.onVideo(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = false,
|
||||||
additionalFilter: CommonMessageFilter<VideoContent>? = null,
|
additionalFilter: CommonMessageFilter<VideoContent>? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VideoContent>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VideoContent>>
|
||||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||||
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||||
import dev.inmo.tgbotapi.extensions.utils.*
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.*
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
|
||||||
import kotlinx.coroutines.flow.filter
|
|
||||||
|
|
||||||
internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
|
internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
@ -31,19 +24,13 @@ internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
|
|||||||
}
|
}
|
||||||
}.let(::listOfNotNull)
|
}.let(::listOfNotNull)
|
||||||
}.subscribeSafelyWithoutExceptions(scope) { triggerMessage ->
|
}.subscribeSafelyWithoutExceptions(scope) { triggerMessage ->
|
||||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
doInSubContextWithUpdatesFilter(
|
||||||
val subFilter = FlowsUpdatesFilter()
|
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||||
|
} else null
|
||||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
) {
|
||||||
val chat = it.sourceChat() ?: return@filter false
|
scenarioReceiver(triggerMessage)
|
||||||
chat.id.chatId == triggerMessage.chat.id.chatId
|
|
||||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
|
||||||
} else {
|
|
||||||
null to this
|
|
||||||
}
|
}
|
||||||
safelyWithoutExceptions { scenario.scenarioReceiver(triggerMessage) }
|
|
||||||
jobToCancel ?.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun BehaviourContext.onChannelEvent(
|
suspend fun BehaviourContext.onChannelEvent(
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
|
|
||||||
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||||
import dev.inmo.tgbotapi.extensions.utils.*
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
||||||
@ -13,12 +11,10 @@ import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
|
|||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
|
||||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||||
import kotlinx.coroutines.flow.filter
|
|
||||||
|
|
||||||
@PreviewFeature
|
@PreviewFeature
|
||||||
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup(
|
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.buildMediaGroupTrigger(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
noinline additionalFilter: (suspend (List<MediaGroupMessage<T>>) -> Boolean)? = null,
|
noinline additionalFilter: (suspend (List<MediaGroupMessage<T>>) -> Boolean)? = null,
|
||||||
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<T>>>
|
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<T>>>
|
||||||
@ -31,45 +27,49 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
|
|||||||
}
|
}
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
}.subscribeSafelyWithoutExceptions(scope) { mediaGroup ->
|
}.subscribeSafelyWithoutExceptions(scope) { mediaGroup ->
|
||||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
val mediaGroupChat = mediaGroup.chat!!
|
||||||
val subFilter = FlowsUpdatesFilter()
|
doInSubContextWithUpdatesFilter(
|
||||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||||
val mediaGroupChat = mediaGroup.chat!!
|
{ it.sourceChat() ?.id ?.chatId == mediaGroupChat.id.chatId }
|
||||||
|
} else null
|
||||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
) {
|
||||||
val chat = it.sourceChat() ?: return@filter false
|
scenarioReceiver(mediaGroup)
|
||||||
chat.id.chatId == mediaGroupChat.id.chatId
|
|
||||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
|
||||||
} else {
|
|
||||||
null to this
|
|
||||||
}
|
}
|
||||||
safelyWithoutExceptions { scenario.scenarioReceiver(mediaGroup) }
|
|
||||||
jobToCancel ?.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.onMediaGroup(
|
||||||
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
|
additionalFilter: (suspend (List<MediaGroupMessage<MediaGroupContent>>) -> Boolean)? = null,
|
||||||
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<MediaGroupContent>>>
|
||||||
|
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onPlaylist(
|
suspend fun BehaviourContext.onPlaylist(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null,
|
additionalFilter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<AudioMediaGroupContent>>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<AudioMediaGroupContent>>>
|
||||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onDocumentsGroup(
|
suspend fun BehaviourContext.onDocumentsGroup(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null,
|
additionalFilter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<DocumentMediaGroupContent>>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<DocumentMediaGroupContent>>>
|
||||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onVisualGallery(
|
suspend fun BehaviourContext.onVisualGallery(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null,
|
additionalFilter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VisualMediaGroupContent>>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VisualMediaGroupContent>>>
|
||||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
|
suspend fun BehaviourContext.onVisualMediaGroup(
|
||||||
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
|
additionalFilter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null,
|
||||||
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VisualMediaGroupContent>>>
|
||||||
|
) = onVisualGallery(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onPhotoGallery(
|
suspend fun BehaviourContext.onPhotoGallery(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null,
|
additionalFilter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<PhotoContent>>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<PhotoContent>>>
|
||||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
suspend fun BehaviourContext.onVideoGallery(
|
suspend fun BehaviourContext.onVideoGallery(
|
||||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||||
additionalFilter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null,
|
additionalFilter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null,
|
||||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VideoContent>>>
|
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VideoContent>>>
|
||||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user