mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 16:23:48 +00:00
preview state of steps
This commit is contained in:
parent
6bd423dc11
commit
00873a255c
@ -8,5 +8,6 @@ pluginManagement {
|
|||||||
include ":tgbotapi.core"
|
include ":tgbotapi.core"
|
||||||
include ":tgbotapi.extensions.api"
|
include ":tgbotapi.extensions.api"
|
||||||
include ":tgbotapi.extensions.utils"
|
include ":tgbotapi.extensions.utils"
|
||||||
|
include ":tgbotapi.extensions.steps"
|
||||||
include ":tgbotapi"
|
include ":tgbotapi"
|
||||||
include ":docs"
|
include ":docs"
|
||||||
|
@ -19,13 +19,17 @@ interface TextedOutput : ParsableOutput, EntitiesOutput
|
|||||||
|
|
||||||
interface TextedInput : Texted {
|
interface TextedInput : Texted {
|
||||||
/**
|
/**
|
||||||
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
* Here must be full list of entities. This list must contains [TextPart]s with
|
||||||
|
* [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] in case if source text contains parts of
|
||||||
|
* regular text
|
||||||
* @see [CaptionedInput.fullEntitiesList]
|
* @see [CaptionedInput.fullEntitiesList]
|
||||||
*/
|
*/
|
||||||
val textEntities: List<TextPart>
|
val textEntities: List<TextPart>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Full list of [TextSource] built from source[TextedInput.textEntities]
|
||||||
|
*
|
||||||
* @see TextedInput.textEntities
|
* @see TextedInput.textEntities
|
||||||
* @see justTextSources
|
* @see justTextSources
|
||||||
*/
|
*/
|
||||||
|
1
tgbotapi.extensions.steps/README.md
Normal file
1
tgbotapi.extensions.steps/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# TelegramBotAPI Steps Extensions
|
48
tgbotapi.extensions.steps/build.gradle
Normal file
48
tgbotapi.extensions.steps/build.gradle
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
}
|
||||||
|
|
||||||
|
project.version = "$library_version"
|
||||||
|
project.group = "$library_group"
|
||||||
|
|
||||||
|
apply from: "publish.gradle"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js(BOTH) {
|
||||||
|
browser()
|
||||||
|
nodejs()
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
implementation kotlin('stdlib')
|
||||||
|
api project(":tgbotapi.core")
|
||||||
|
api project(":tgbotapi.extensions.utils")
|
||||||
|
api project(":tgbotapi.extensions.api")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
tgbotapi.extensions.steps/mpp_publish_template.kpsb
Normal file
1
tgbotapi.extensions.steps/mpp_publish_template.kpsb
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Steps Extensions","description":"These extensions project contains tools for simple interaction with chats","url":"https://insanusmokrassar.github.io/TelegramBotAPI/tgbotapi.extensions.steps","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
|
69
tgbotapi.extensions.steps/publish.gradle
Normal file
69
tgbotapi.extensions.steps/publish.gradle
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
apply plugin: 'maven-publish'
|
||||||
|
|
||||||
|
task javadocsJar(type: Jar) {
|
||||||
|
classifier = 'javadoc'
|
||||||
|
}
|
||||||
|
task sourceJar (type : Jar) {
|
||||||
|
classifier = 'sources'
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
project.publishing.publications.all {
|
||||||
|
// rename artifacts
|
||||||
|
groupId "${project.group}"
|
||||||
|
if (it.name.contains('kotlinMultiplatform')) {
|
||||||
|
artifactId = "${project.name}"
|
||||||
|
artifact sourceJar
|
||||||
|
} else {
|
||||||
|
artifactId = "${project.name}-$name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications.all {
|
||||||
|
artifact javadocsJar
|
||||||
|
|
||||||
|
pom {
|
||||||
|
description = "These extensions project contains tools for simple interaction with chats"
|
||||||
|
name = "Telegram Bot API Steps Extensions"
|
||||||
|
url = "https://insanusmokrassar.github.io/TelegramBotAPI/tgbotapi.extensions.steps"
|
||||||
|
|
||||||
|
scm {
|
||||||
|
developerConnection = "scm:git:[fetch=]https://github.com/insanusmokrassar/TelegramBotAPI.git[push=]https://github.com/insanusmokrassar/TelegramBotAPI.git"
|
||||||
|
url = "https://github.com/insanusmokrassar/TelegramBotAPI.git"
|
||||||
|
}
|
||||||
|
|
||||||
|
developers {
|
||||||
|
|
||||||
|
developer {
|
||||||
|
id = "InsanusMokrassar"
|
||||||
|
name = "Ovsiannikov Aleksei"
|
||||||
|
email = "ovsyannikov.alexey95@gmail.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
licenses {
|
||||||
|
|
||||||
|
license {
|
||||||
|
name = "Apache Software License 2.0"
|
||||||
|
url = "https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "bintray"
|
||||||
|
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/TelegramBotAPI/${project.name}/;publish=1;override=1")
|
||||||
|
credentials {
|
||||||
|
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
|
||||||
|
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.steps
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
typealias ScenarioReceiver<T> = suspend Scenario.() -> T
|
||||||
|
typealias ScenarioAndTypeReceiver<T, I> = suspend Scenario.(I) -> T
|
||||||
|
|
||||||
|
data class Scenario(
|
||||||
|
val bot: TelegramBot,
|
||||||
|
val flowsUpdatesFilter: FlowsUpdatesFilter,
|
||||||
|
val scope: CoroutineScope
|
||||||
|
)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.steps
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
suspend fun TelegramBot.buildScenarios(
|
||||||
|
scope: CoroutineScope,
|
||||||
|
flowUpdatesFilter: FlowsUpdatesFilter = FlowsUpdatesFilter(),
|
||||||
|
block: ScenarioReceiver<Unit>
|
||||||
|
) {
|
||||||
|
Scenario(
|
||||||
|
this,
|
||||||
|
flowUpdatesFilter,
|
||||||
|
scope
|
||||||
|
).block()
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.steps.expectations
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.extensions.steps.Scenario
|
||||||
|
import dev.inmo.tgbotapi.extensions.steps.ScenarioReceiver
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
|
private val cancelledByFilterException = CancellationException("Cancelled by filter precreatedException")
|
||||||
|
|
||||||
|
typealias RequestBuilder<T> = suspend (Update) -> Request<T>
|
||||||
|
typealias NullableRequestBuilder<T> = suspend (Update) -> Request<T>?
|
||||||
|
|
||||||
|
@RiskFeature("This method is not very comfortable to use and too low-level. It is recommended to use methods which already included into library")
|
||||||
|
suspend fun <T> FlowsUpdatesFilter.expectFlow(
|
||||||
|
bot: TelegramBot,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
count: Int? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelRequestFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
|
||||||
|
filter: suspend (Update) -> T?
|
||||||
|
): Flow<T> {
|
||||||
|
val flow = allUpdatesFlow.mapNotNull {
|
||||||
|
val result = safelyWithoutExceptions { filter(it) }
|
||||||
|
if (result == null) {
|
||||||
|
if (cancelTrigger(it)) {
|
||||||
|
cancelRequestFactory(it) ?.also {
|
||||||
|
safelyWithoutExceptions { bot.execute(it) }
|
||||||
|
throw cancelledByFilterException
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errorFactory(it) ?.also { errorRequest ->
|
||||||
|
safelyWithoutExceptions { bot.execute(errorRequest) }
|
||||||
|
}
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val result = if (count == null) {
|
||||||
|
flow
|
||||||
|
} else {
|
||||||
|
flow.take(count)
|
||||||
|
}
|
||||||
|
initRequest ?.also { safelyWithoutExceptions { bot.execute(initRequest) } }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun <T> Scenario.expectFlow(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
count: Int? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelRequestFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
|
||||||
|
filter: suspend (Update) -> T?
|
||||||
|
) = flowsUpdatesFilter.expectFlow(bot, initRequest, count, errorFactory, cancelRequestFactory, cancelTrigger, filter)
|
||||||
|
|
||||||
|
@RiskFeature("This method is not very comfortable to use and too low-level. It is recommended to use methods which already included into library")
|
||||||
|
suspend fun <T> FlowsUpdatesFilter.expectOne(
|
||||||
|
bot: TelegramBot,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelRequestFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
|
||||||
|
filter: suspend (Update) -> T?,
|
||||||
|
): T = expectFlow(bot, initRequest, 1, errorFactory, cancelRequestFactory, cancelTrigger, filter).first()
|
||||||
|
|
||||||
|
suspend fun <T> Scenario.expectOne(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelRequestFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
|
||||||
|
filter: suspend (Update) -> T?
|
||||||
|
) = flowsUpdatesFilter.expectOne(bot, initRequest, errorFactory, cancelRequestFactory, cancelTrigger, filter)
|
@ -0,0 +1,175 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.steps.expectations
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.steps.Scenario
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
|
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 kotlinx.coroutines.flow.toList
|
||||||
|
|
||||||
|
typealias ContentMessageToContentMapper<T> = suspend ContentMessage<T>.() -> T?
|
||||||
|
|
||||||
|
private suspend fun <O> Scenario.waitContentMessage(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
mapper: suspend ContentMessage<MessageContent>.() -> O?
|
||||||
|
): List<O> = expectFlow(
|
||||||
|
initRequest,
|
||||||
|
count,
|
||||||
|
errorFactory
|
||||||
|
) {
|
||||||
|
it.asMessageUpdate() ?.data ?.asContentMessage() ?.mapper()
|
||||||
|
}.toList().toList()
|
||||||
|
|
||||||
|
private suspend inline fun <reified T : MessageContent> Scenario.waitContent(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
noinline filter: (suspend (ContentMessage<T>) -> T?)? = null
|
||||||
|
) : List<T> = waitContentMessage<T>(
|
||||||
|
count,
|
||||||
|
initRequest,
|
||||||
|
errorFactory
|
||||||
|
) {
|
||||||
|
if (content is T) {
|
||||||
|
val message = (this as ContentMessage<T>)
|
||||||
|
if (filter == null) {
|
||||||
|
message.content
|
||||||
|
} else {
|
||||||
|
filter(message)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun Scenario.waitContact(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<ContactContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitDice(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<DiceContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitGame(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<GameContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitLocation(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<LocationContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitPoll(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<PollContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitText(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<TextContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitVenue(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<VenueContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitAudioMediaGroup(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<AudioMediaGroupContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitDocumentMediaGroup(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<DocumentMediaGroupContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitMedia(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<MediaContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitMediaGroup(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<MediaGroupContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitVisualMediaGroup(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<VisualMediaGroupContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitAnimation(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<AnimationContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitAudio(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<AudioContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitDocument(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<DocumentContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitPhoto(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<PhotoContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitSticker(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<StickerContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitVideo(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<VideoContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitVideoNote(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<VideoNoteContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitVoice(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<VoiceContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
||||||
|
suspend fun Scenario.waitInvoice(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: ContentMessageToContentMapper<InvoiceContent>? = null
|
||||||
|
) = waitContent(count, initRequest, errorFactory, filter)
|
@ -0,0 +1,37 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.steps.triggers_handling
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.textSources
|
||||||
|
import dev.inmo.tgbotapi.extensions.steps.*
|
||||||
|
import dev.inmo.tgbotapi.extensions.steps.expectations.expectFlow
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||||
|
|
||||||
|
suspend fun Scenario.command(
|
||||||
|
commandRegex: Regex,
|
||||||
|
requireOnlyCommandInMessage: Boolean = true,
|
||||||
|
scenarioReceiver: ScenarioAndTypeReceiver<Unit, ContentMessage<TextContent>>
|
||||||
|
) {
|
||||||
|
flowsUpdatesFilter.expectFlow(bot) {
|
||||||
|
it.asMessageUpdate() ?.data ?.asContentMessage() ?.let { message ->
|
||||||
|
message.content.asTextContent() ?.let {
|
||||||
|
val textSources = it.textSources
|
||||||
|
val sizeRequirement = if (requireOnlyCommandInMessage) {
|
||||||
|
textSources.size == 1
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
if (sizeRequirement && textSources.any { commandRegex.matches(it.asBotCommandTextSource() ?.command ?: return@any false) }) {
|
||||||
|
message as ContentMessage<TextContent>
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.subscribeSafelyWithoutExceptions(scope) {
|
||||||
|
scenarioReceiver(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user