mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-09-03 07:09:23 +00:00
improving work of behaviour_builder
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package dev.inmo.tgbotapi.extensions.behaviour_builder
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
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.UpdatesFilter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.filter
|
||||
|
||||
typealias BehaviourContextReceiver<T> = suspend BehaviourContext.() -> T
|
||||
typealias BehaviourContextAndTypeReceiver<T, I> = suspend BehaviourContext.(I) -> T
|
||||
@@ -19,4 +21,48 @@ data class BehaviourContext(
|
||||
val bot: TelegramBot,
|
||||
val scope: CoroutineScope,
|
||||
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(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
@@ -101,14 +107,14 @@ suspend fun BehaviourContext.waitVenue(
|
||||
count: Int = 1,
|
||||
filter: CommonMessageToContentMapper<VenueContent>? = null
|
||||
) = waitContent(count, initRequest, false, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitAudioMediaGroup(
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
filter: CommonMessageToContentMapper<AudioMediaGroupContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroup(
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
@@ -119,17 +125,17 @@ suspend fun BehaviourContext.waitMedia(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
filter: CommonMessageToContentMapper<MediaContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitMediaGroup(
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
filter: CommonMessageToContentMapper<MediaGroupContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitVisualMediaGroup(
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
@@ -146,21 +152,21 @@ suspend fun BehaviourContext.waitAudio(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
filter: CommonMessageToContentMapper<AudioContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitDocument(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
filter: CommonMessageToContentMapper<DocumentContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitPhoto(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
filter: CommonMessageToContentMapper<PhotoContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitSticker(
|
||||
@@ -173,7 +179,7 @@ suspend fun BehaviourContext.waitVideo(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
filter: CommonMessageToContentMapper<VideoContent>? = null
|
||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitVideoNote(
|
||||
|
@@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.toList
|
||||
|
||||
@PreviewFeature
|
||||
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup(
|
||||
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.buildMediaGroupWaiter(
|
||||
count: Int = 1,
|
||||
initRequest: Request<*>? = null,
|
||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||
@@ -21,7 +21,7 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
|
||||
update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
|
||||
if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup as List<MediaGroupMessage<T>>))) {
|
||||
listOf(
|
||||
mediaGroup.map { it.content as T } as List<MediaGroupMessage<T>>
|
||||
mediaGroup.map { it.content as T }
|
||||
)
|
||||
} else {
|
||||
null
|
||||
@@ -29,33 +29,39 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
|
||||
} ?: emptyList()
|
||||
}.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(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
filter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null
|
||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
||||
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitDocumentsGroup(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
filter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null
|
||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
||||
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitVisualGallery(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
filter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null
|
||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
||||
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitPhotoGallery(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
filter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null
|
||||
) = onMediaGroup(count, initRequest, errorFactory, filter)
|
||||
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
|
||||
suspend fun BehaviourContext.waitVideoGallery(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
count: Int = 1,
|
||||
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
|
||||
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||
import dev.inmo.tgbotapi.extensions.utils.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
||||
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(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
@@ -27,19 +21,15 @@ internal suspend inline fun <reified T : CallbackQuery> BehaviourContext.onCallb
|
||||
}
|
||||
}.let(::listOfNotNull)
|
||||
}.subscribeSafelyWithoutExceptions(scope) { triggerQuery ->
|
||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
||||
val subFilter = FlowsUpdatesFilter()
|
||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
||||
|
||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
||||
val chat = it.sourceChat() ?: return@filter false
|
||||
chat.id.chatId == triggerQuery.user.id.chatId
|
||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
||||
} else {
|
||||
null to this
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerQuery.user.id.chatId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
) {
|
||||
scenarioReceiver(triggerQuery)
|
||||
}
|
||||
safelyWithoutExceptions { scenario.scenarioReceiver(triggerQuery) }
|
||||
jobToCancel ?.cancel()
|
||||
}
|
||||
|
||||
|
||||
|
@@ -26,6 +26,12 @@ suspend fun BehaviourContext.command(
|
||||
},
|
||||
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(
|
||||
commandRegex: Regex,
|
||||
@@ -33,3 +39,10 @@ suspend inline fun BehaviourContext.onCommand(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
|
||||
): 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
|
||||
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||
import dev.inmo.tgbotapi.extensions.utils.*
|
||||
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.media.*
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||
import kotlinx.coroutines.flow.filter
|
||||
|
||||
typealias CommonMessageFilter<T> = (suspend (CommonMessage<T>) -> Boolean)
|
||||
|
||||
@@ -50,21 +45,22 @@ internal suspend inline fun <reified T : MessageContent> BehaviourContext.onCont
|
||||
}
|
||||
}.let(::listOfNotNull)
|
||||
}.subscribeSafelyWithoutExceptions(scope) { triggerMessage ->
|
||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
||||
val subFilter = FlowsUpdatesFilter()
|
||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
||||
|
||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
||||
val chat = it.sourceChat() ?: return@filter false
|
||||
chat.id.chatId == triggerMessage.chat.id.chatId
|
||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
||||
} else {
|
||||
null to this
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
) {
|
||||
scenarioReceiver(triggerMessage)
|
||||
}
|
||||
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(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: CommonMessageFilter<ContactContent>? = null,
|
||||
@@ -105,7 +101,7 @@ suspend fun BehaviourContext.onAudioMediaGroup(
|
||||
additionalFilter: CommonMessageFilter<AudioMediaGroupContent>? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioMediaGroupContent>>
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onDocumentMediaGroup(
|
||||
suspend fun BehaviourContext.onDocumentMediaGroupContent(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
includeMediaGroups: Boolean = true,
|
||||
additionalFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null,
|
||||
@@ -113,7 +109,7 @@ suspend fun BehaviourContext.onDocumentMediaGroup(
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onMediaCollection(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
additionalFilter: (suspend (CommonMessage<MediaCollectionContent<TelegramMediaFile>>) -> Boolean)? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>>
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||
@@ -123,18 +119,6 @@ suspend fun BehaviourContext.onMedia(
|
||||
additionalFilter: CommonMessageFilter<MediaContent>? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaContent>>
|
||||
) = 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(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: CommonMessageFilter<AnimationContent>? = null,
|
||||
@@ -142,19 +126,19 @@ suspend fun BehaviourContext.onAnimation(
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onAudio(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
additionalFilter: CommonMessageFilter<AudioContent>? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioContent>>
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onDocument(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
additionalFilter: CommonMessageFilter<DocumentContent>? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<DocumentContent>>
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onPhoto(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
additionalFilter: CommonMessageFilter<PhotoContent>? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<PhotoContent>>
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||
@@ -165,7 +149,7 @@ suspend fun BehaviourContext.onSticker(
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onVideo(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
includeMediaGroups: Boolean = true,
|
||||
includeMediaGroups: Boolean = false,
|
||||
additionalFilter: CommonMessageFilter<VideoContent>? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VideoContent>>
|
||||
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
|
||||
|
@@ -1,21 +1,14 @@
|
||||
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.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||
import dev.inmo.tgbotapi.extensions.utils.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
||||
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(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
@@ -31,19 +24,13 @@ internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
|
||||
}
|
||||
}.let(::listOfNotNull)
|
||||
}.subscribeSafelyWithoutExceptions(scope) { triggerMessage ->
|
||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
||||
val subFilter = FlowsUpdatesFilter()
|
||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
||||
|
||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
||||
val chat = it.sourceChat() ?: return@filter false
|
||||
chat.id.chatId == triggerMessage.chat.id.chatId
|
||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
||||
} else {
|
||||
null to this
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId }
|
||||
} else null
|
||||
) {
|
||||
scenarioReceiver(triggerMessage)
|
||||
}
|
||||
safelyWithoutExceptions { scenario.scenarioReceiver(triggerMessage) }
|
||||
jobToCancel ?.cancel()
|
||||
}
|
||||
|
||||
suspend fun BehaviourContext.onChannelEvent(
|
||||
|
@@ -2,10 +2,8 @@
|
||||
|
||||
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.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
|
||||
import dev.inmo.tgbotapi.extensions.utils.*
|
||||
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.content.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||
import kotlinx.coroutines.flow.filter
|
||||
|
||||
@PreviewFeature
|
||||
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup(
|
||||
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.buildMediaGroupTrigger(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
noinline additionalFilter: (suspend (List<MediaGroupMessage<T>>) -> Boolean)? = null,
|
||||
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<T>>>
|
||||
@@ -31,45 +27,49 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
|
||||
}
|
||||
} ?: emptyList()
|
||||
}.subscribeSafelyWithoutExceptions(scope) { mediaGroup ->
|
||||
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
|
||||
val subFilter = FlowsUpdatesFilter()
|
||||
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
|
||||
val mediaGroupChat = mediaGroup.chat!!
|
||||
|
||||
flowsUpdatesFilter.allUpdatesFlow.filter {
|
||||
val chat = it.sourceChat() ?: return@filter false
|
||||
chat.id.chatId == mediaGroupChat.id.chatId
|
||||
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
|
||||
} else {
|
||||
null to this
|
||||
val mediaGroupChat = mediaGroup.chat!!
|
||||
doInSubContextWithUpdatesFilter(
|
||||
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
|
||||
{ it.sourceChat() ?.id ?.chatId == mediaGroupChat.id.chatId }
|
||||
} else null
|
||||
) {
|
||||
scenarioReceiver(mediaGroup)
|
||||
}
|
||||
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(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<AudioMediaGroupContent>>>
|
||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onDocumentsGroup(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<DocumentMediaGroupContent>>>
|
||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onVisualGallery(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null,
|
||||
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(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<PhotoContent>>>
|
||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
suspend fun BehaviourContext.onVideoGallery(
|
||||
includeFilterByChatInBehaviourSubContext: Boolean = true,
|
||||
additionalFilter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null,
|
||||
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VideoContent>>>
|
||||
) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
) = buildMediaGroupTrigger(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
|
||||
|
||||
|
Reference in New Issue
Block a user