1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-22 16:23:48 +00:00

ContentMessage -> CommonMessage in behaviour_builder, fill readme of behaviour_builder and update projects schema

This commit is contained in:
InsanusMokrassar 2021-01-08 16:28:00 +06:00
parent b9341f89ac
commit 9cc402b42d
9 changed files with 779 additions and 589 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<minder version="1.11.1"> <minder version="1.11.3">
<theme name="default" label="Default" index="-1"/> <theme name="default" label="Default" index="0"/>
<styles> <styles>
<style level="0" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/> <style level="0" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="1" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/> <style level="1" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
@ -14,44 +14,53 @@
<style level="9" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/> <style level="9" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="10" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/> <style level="10" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
</styles> </styles>
<drawarea x="-320.56697591145837" y="-10.028254191080691" scale="0.75"/> <drawarea x="-950.47548925255796" y="-49.650554065281653" scale="0.5"/>
<images/> <images/>
<nodes> <nodes>
<node id="0" posx="748.88964843749955" posy="119.42341613769531" width="472" height="168" side="top" fold="false" treesize="603" layout="Downwards" group="false"> <node id="0" posx="1378.798161778599" posy="159.04571601189673" width="472" height="168" side="top" fold="false" treesize="743" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="439" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/> <style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="439" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="764.88964843749955" posy="135.42341613769531" maxwidth="488.96484375"> <nodename posx="1394.798161778599" posy="175.04571601189673" maxwidth="488.96484375">
<text data="tgbotapi.core&#10;&#10;Root project with API. It is not recommended to use its requests directly and better to use at least tgbotapi.extensions.api"/> <text data="tgbotapi.core&#10;&#10;Root project with API. It is not recommended to use its requests directly and better to use at least tgbotapi.extensions.api"/>
</nodename> </nodename>
<nodenote></nodenote> <nodenote></nodenote>
<nodes> <nodes>
<node id="1" posx="781.88964843749955" posy="387.42341613769531" width="406" height="145" side="bottom" fold="false" treesize="603" color="#68b723" colorroot="true" layout="Downwards" group="false"> <node id="1" posx="1411.798161778599" posy="427.04571601189673" width="406" height="145" side="bottom" fold="false" treesize="743" color="#68b723" colorroot="true" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="none" nodewidth="394" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/> <style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="none" nodewidth="394" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="797.88964843749955" posy="403.42341613769531" maxwidth="419.451171875"> <nodename posx="1427.798161778599" posy="443.04571601189673" maxwidth="419.451171875">
<text data="TelegramBotAPI extensions&#10;&#10;Family of projects which are fully based on TelegramBotAPI and extend its functionality"/> <text data="TelegramBotAPI extensions&#10;&#10;Family of projects which are fully based on TelegramBotAPI and extend its functionality"/>
</nodename> </nodename>
<nodenote></nodenote> <nodenote></nodenote>
<nodes> <nodes>
<node id="2" posx="683.38964843749955" posy="632.42341613769531" width="296" height="191" side="bottom" fold="false" treesize="296" color="#68b723" colorroot="true" layout="Downwards" group="false"> <node id="2" posx="1247.298161778599" posy="672.04571601189673" width="296" height="191" side="bottom" fold="false" treesize="296" color="#68b723" colorroot="true" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="203" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/> <style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="203" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="699.38964843749955" posy="648.42341613769531" maxwidth="295.90315755208337"> <nodename posx="1263.298161778599" posy="688.04571601189673" maxwidth="295.90315755208337">
<text data="tgbotapi.extensions.api&#10;&#10;Extensions project for make requests more look like in the Telegram Bot API and give opportunity to use it's easier"/> <text data="tgbotapi.extensions.api&#10;&#10;Extensions project for make requests more look like in the Telegram Bot API and give opportunity to use it's easier"/>
</nodename> </nodename>
<nodenote></nodenote> <nodenote></nodenote>
</node> </node>
<node id="3" posx="979.38964843749955" posy="632.42341613769531" width="307" height="168" side="bottom" fold="false" treesize="307" color="#68b723" colorroot="true" layout="Downwards" group="false"> <node id="3" posx="1609.298161778599" posy="672.04571601189673" width="307" height="168" side="bottom" fold="false" treesize="439" color="#68b723" colorroot="true" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="286" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/> <style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="286" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="995.38964843749955" posy="648.42341613769531" maxwidth="299.252197265625"> <nodename posx="1625.298161778599" posy="688.04571601189673" maxwidth="299.252197265625">
<text data="tgbotapi.extensions.utils&#10;&#10;Extensions project with utils things which will make easier different operations"/> <text data="tgbotapi.extensions.utils&#10;&#10;Extensions project with utils things which will make easier different operations"/>
</nodename> </nodename>
<nodenote></nodenote> <nodenote></nodenote>
<nodes>
<node id="6" posx="1543.298161778599" posy="940.04571601189673" width="439" height="122" side="bottom" fold="false" treesize="439" color="#68b723" colorroot="false" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="387" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1559.298161778599" posy="956.04571601189673" maxwidth="408.97932942708348">
<text data="tgbotapi.extensions.behaviour_builder&#10;&#10;Extension project for building bot behaviour via special dsl"/>
</nodename>
<nodenote></nodenote>
</node>
</nodes>
</node> </node>
</nodes> </nodes>
</node> </node>
</nodes> </nodes>
</node> </node>
<node id="4" posx="815.52319335937455" posy="948.04447937011719" width="329" height="213" side="top" fold="false" treesize="329" layout="Downwards" group="false"> <node id="4" posx="1439.623926752558" posy="1175.0700181766106" width="329" height="213" side="top" fold="false" treesize="329" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="388" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/> <style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="388" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="831.52319335937455" posy="964.04447937011719" maxwidth="394.3671875"> <nodename posx="1455.623926752558" posy="1191.0700181766106" maxwidth="394.3671875">
<text data="tgbotapi&#10;&#10;Here included all available TelegramBotAPI libraries:&#13;&#10;&#13;&#10;* tgbotapi.core&#13;&#10;* tgbotapi.extensions.api&#13;&#10;* tgbotapi.extensions.utils"> <text data="tgbotapi&#10;&#10;Here included all available TelegramBotAPI libraries:&#13;&#10;&#13;&#10;* tgbotapi.core&#13;&#10;* tgbotapi.extensions.api&#13;&#10;* tgbotapi.extensions.utils">
<color> <color>
<range start="67" end="68" extra="rgb(255,0,0)"/> <range start="67" end="68" extra="rgb(255,0,0)"/>
@ -70,6 +79,7 @@
<range start="67" end="68" extra="rgb(255,0,0)"/> <range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/> <range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/> <range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/> <range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/> <range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/> <range start="84" end="85" extra="rgb(255,0,0)"/>
@ -86,6 +96,8 @@
<range start="84" end="85" extra="rgb(255,0,0)"/> <range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/> <range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/> <range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/> <range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/> <range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/> <range start="111" end="112" extra="rgb(255,0,0)"/>
@ -110,12 +122,17 @@
</nodes> </nodes>
<groups/> <groups/>
<connections> <connections>
<connection from_id="2" to_id="4" drag_x="905.70642089843705" drag_y="891.23394775390625" color="#777777"> <connection from_id="2" to_id="4" drag_x="1499.7110442655758" drag_y="1024.5578670942541" color="#777777">
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/> <style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<title></title> <title></title>
<note></note> <note></note>
</connection> </connection>
<connection from_id="3" to_id="4" drag_x="1056.456420898437" drag_y="885.48394775390625" color="#777777"> <connection from_id="6" to_id="4" drag_x="1683.4610442655785" drag_y="1141.3078670942537" color="#777777">
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<title></title>
<note></note>
</connection>
<connection from_id="3" to_id="4" drag_x="1535.16259765625" drag_y="911.280029296875">
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/> <style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<title></title> <title></title>
<note></note> <note></note>

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -1 +1,62 @@
# TelegramBotAPI Steps Extensions # TelegramBotAPI Behaviour Builder Extensions
This extension was created to make it more simple to build bot steps handling. Usually, you must use something like:
```kotlin
val bot = telegramBot(TOKEN)
bot.startGettingFlowsUpdatesByLongPolling {
messagesFlow.subscribeSafelyWithoutExceptions {
// ...
}
// here I already tired to write this example 😫
}
```
This library offer other way to do a lot of routine in more simple way:
```kotlin
telegramBot(token) {
onCommand("start".regex) {
execute(SendTextMessage(it.chat.id, "This bot can ...")) // replaceable with reply(it, "This bot can ...") when you are using `tgbotapi.extensions.api`
}
}
```
## Triggers
In terminology of this project the `Triggers` are things which have no initial message, may have own filter for incoming
messages and filter messages for context which will be used in subcontext. Full syntax with `onText` as an example:
```kotlin
telegramBot(TOKEN) {
onText(
includeFilterByChatInBehaviourSubContext = true, // if false - last lambda will receive all messages instead of filtered by chat messages
additionalFilter = { message: CommonMessage<TextContent> ->
// here you may check incoming message for any requirements before it will be passed to the main lambda
}
) { message: CommonMessage<TextContent> -> // this here is `BehaviourContext`
// here put your actions and additional waiters
}
}
```
## Waiters
Waiters targeted to get some content "here and now", they must be used inside some trigger main lambda:
```kotlin
telegramBot(TOKEN) {
onCommand("start") { message: CommonMessage<TextContent> ->
val userPhotos = waitPhoto(
SendTextMessage(it.chat.id, "Ok, send me some photo, please"), // init request, can be any `Request` object
{ update: Update -> // That is update which is NOT passed requirements. In current context we expect some photo, but received something else
SendTextMessage(it.chat.id, "Excuse me, but I can accept only photos") // it could be null
},
2, // some count of photos
includeMediaGroups = true, // if false, messages related to some media group will be skipped and recognized as incorrect
) { message: CommonMessate<PhotoContent> -> // this method is optional and you can use it in case you want to add some additional requirements checks
message.content // return null if message didn't passed requirements
}
}
}
```

View File

@ -39,9 +39,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib') implementation kotlin('stdlib')
api project(":tgbotapi.core")
api project(":tgbotapi.extensions.utils") api project(":tgbotapi.extensions.utils")
api project(":tgbotapi.extensions.api")
} }
} }
} }

View File

@ -2,10 +2,11 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.types.message.content.abstracts.*
@ -13,14 +14,14 @@ 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 kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
typealias ContentMessageToContentMapper<T> = suspend ContentMessage<T>.() -> T? typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
private suspend fun <O> BehaviourContext.waitContentMessage( private suspend fun <O> BehaviourContext.waitCommonMessage(
count: Int = 1, count: Int = 1,
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
mapper: suspend ContentMessage<MessageContent>.() -> O? mapper: suspend CommonMessage<MessageContent>.() -> O?
): List<O> = expectFlow( ): List<O> = expectFlow(
initRequest, initRequest,
count, count,
@ -28,10 +29,10 @@ private suspend fun <O> BehaviourContext.waitContentMessage(
) { ) {
if (includeMediaGroups) { if (includeMediaGroups) {
it.asSentMediaGroupUpdate() ?.data ?.mapNotNull { it.asSentMediaGroupUpdate() ?.data ?.mapNotNull {
(it as ContentMessage<MessageContent>).mapper() (it as CommonMessage<MessageContent>).mapper()
} ?.let { return@expectFlow it } } ?.let { return@expectFlow it }
} }
it.asMessageUpdate() ?.data ?.asContentMessage() ?.mapper().let(::listOfNotNull) it.asMessageUpdate() ?.data ?.asCommonMessage() ?.mapper().let(::listOfNotNull)
}.toList().toList() }.toList().toList()
private suspend inline fun <reified T : MessageContent> BehaviourContext.waitContent( private suspend inline fun <reified T : MessageContent> BehaviourContext.waitContent(
@ -39,8 +40,8 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null },
noinline filter: ContentMessageToContentMapper<T>? = null noinline filter: CommonMessageToContentMapper<T>? = null
) : List<T> = waitContentMessage<T>( ) : List<T> = waitCommonMessage<T>(
count, count,
initRequest, initRequest,
includeMediaGroups, includeMediaGroups,
@ -48,11 +49,11 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
) { ) {
if (content is T) { if (content is T) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val message = (this as ContentMessage<T>) val message = (this as CommonMessage<T>)
if (filter == null) { if (filter == null) {
message.content message.content
} else { } else {
filter(message) safelyWithoutExceptions { filter(message) }
} }
} else { } else {
null null
@ -63,134 +64,134 @@ suspend fun BehaviourContext.waitContact(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<ContactContent>? = null filter: CommonMessageToContentMapper<ContactContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitDice( suspend fun BehaviourContext.waitDice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<DiceContent>? = null filter: CommonMessageToContentMapper<DiceContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitGame( suspend fun BehaviourContext.waitGame(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<GameContent>? = null filter: CommonMessageToContentMapper<GameContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitLocation( suspend fun BehaviourContext.waitLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<LocationContent>? = null filter: CommonMessageToContentMapper<LocationContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitPoll( suspend fun BehaviourContext.waitPoll(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<PollContent>? = null filter: CommonMessageToContentMapper<PollContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitText( suspend fun BehaviourContext.waitText(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<TextContent>? = null filter: CommonMessageToContentMapper<TextContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitVenue( suspend fun BehaviourContext.waitVenue(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<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.waitAudioMediaGroup(
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: ContentMessageToContentMapper<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.waitDocumentMediaGroup(
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: ContentMessageToContentMapper<DocumentMediaGroupContent>? = null filter: CommonMessageToContentMapper<DocumentMediaGroupContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter) ) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
suspend fun BehaviourContext.waitMedia( 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 = true,
filter: ContentMessageToContentMapper<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.waitMediaGroup(
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: ContentMessageToContentMapper<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.waitVisualMediaGroup(
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: ContentMessageToContentMapper<VisualMediaGroupContent>? = null filter: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter) ) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter)
suspend fun BehaviourContext.waitAnimation( suspend fun BehaviourContext.waitAnimation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<AnimationContent>? = null filter: CommonMessageToContentMapper<AnimationContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitAudio( 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 = true,
filter: ContentMessageToContentMapper<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 = true,
filter: ContentMessageToContentMapper<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 = true,
filter: ContentMessageToContentMapper<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(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<StickerContent>? = null filter: CommonMessageToContentMapper<StickerContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitVideo( 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 = true,
filter: ContentMessageToContentMapper<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(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<VideoNoteContent>? = null filter: CommonMessageToContentMapper<VideoNoteContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitVoice( suspend fun BehaviourContext.waitVoice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<VoiceContent>? = null filter: CommonMessageToContentMapper<VoiceContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)
suspend fun BehaviourContext.waitInvoice( suspend fun BehaviourContext.waitInvoice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: ContentMessageToContentMapper<InvoiceContent>? = null filter: CommonMessageToContentMapper<InvoiceContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter) ) = waitContent(count, initRequest, false, errorFactory, filter)

View File

@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.CommonAbstracts.textSources import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -11,7 +11,7 @@ suspend fun BehaviourContext.command(
commandRegex: Regex, commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<TextContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
): Job = onText( ): Job = onText(
includeFilterByChatInBehaviourSubContext, includeFilterByChatInBehaviourSubContext,
{ message -> { message ->
@ -31,5 +31,5 @@ suspend inline fun BehaviourContext.onCommand(
commandRegex: Regex, commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<TextContent>> noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
): Job = command(commandRegex, requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, scenarioReceiver) ): Job = command(commandRegex, requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, scenarioReceiver)

View File

@ -11,7 +11,7 @@ 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.files.abstracts.TelegramMediaFile import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.* 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.*
@ -20,18 +20,19 @@ import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.utils.PreviewFeature import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
typealias CommonMessageFilter<T> = (suspend (CommonMessage<T>) -> Boolean)
@PreviewFeature @PreviewFeature
internal suspend inline fun <reified T : MessageContent> BehaviourContext.onContent( internal suspend inline fun <reified T : MessageContent> BehaviourContext.onContent(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
noinline additionalFilter: (suspend (ContentMessage<T>) -> Boolean)? = null, noinline additionalFilter: CommonMessageFilter<T>? = null,
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<T>> noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<T>>
) = flowsUpdatesFilter.expectFlow(bot) { ) = flowsUpdatesFilter.expectFlow(bot) {
if (includeMediaGroups) { if (includeMediaGroups) {
it.asSentMediaGroupUpdate() ?.data ?.mapNotNull { it.asSentMediaGroupUpdate() ?.data ?.mapNotNull {
if (it.content is T) { if (it.content is T) {
val adaptedMessage = it as ContentMessage<T> val adaptedMessage = it as CommonMessage<T>
if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null
} else { } else {
null null
@ -40,9 +41,9 @@ internal suspend inline fun <reified T : MessageContent> BehaviourContext.onCont
return@expectFlow it return@expectFlow it
} }
} }
it.asMessageUpdate() ?.data ?.asContentMessage() ?.let { message -> it.asMessageUpdate() ?.data ?.asCommonMessage() ?.let { message ->
if (message.content is T) { if (message.content is T) {
val adaptedMessage = message as ContentMessage<T> val adaptedMessage = message as CommonMessage<T>
if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null
} else { } else {
null null
@ -66,120 +67,120 @@ internal suspend inline fun <reified T : MessageContent> BehaviourContext.onCont
suspend fun BehaviourContext.onContact( suspend fun BehaviourContext.onContact(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<ContactContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<ContactContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<ContactContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<ContactContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onDice( suspend fun BehaviourContext.onDice(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<DiceContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<DiceContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<DiceContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<DiceContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onGame( suspend fun BehaviourContext.onGame(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<GameContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<GameContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<GameContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<GameContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onLocation( suspend fun BehaviourContext.onLocation(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<LocationContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<LocationContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<LocationContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<LocationContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onPoll( suspend fun BehaviourContext.onPoll(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<PollContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<PollContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<PollContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<PollContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onText( suspend fun BehaviourContext.onText(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<TextContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<TextContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<TextContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<TextContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVenue( suspend fun BehaviourContext.onVenue(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<VenueContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<VenueContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<VenueContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VenueContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onAudioMediaGroup( suspend fun BehaviourContext.onAudioMediaGroup(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<AudioMediaGroupContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<AudioMediaGroupContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<AudioMediaGroupContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AudioMediaGroupContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onDocumentMediaGroup( suspend fun BehaviourContext.onDocumentMediaGroup(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
additionalFilter: (suspend (ContentMessage<DocumentMediaGroupContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<DocumentMediaGroupContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<DocumentMediaGroupContent>>
) = 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 = true,
additionalFilter: (suspend (ContentMessage<MediaCollectionContent<TelegramMediaFile>>) -> Boolean)? = null, additionalFilter: (suspend (CommonMessage<MediaCollectionContent<TelegramMediaFile>>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<MediaCollectionContent<TelegramMediaFile>>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>>
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onMedia( suspend fun BehaviourContext.onMedia(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
additionalFilter: (suspend (ContentMessage<MediaContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<MediaContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<MediaContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onMediaGroup( suspend fun BehaviourContext.onMediaGroup(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
additionalFilter: (suspend (ContentMessage<MediaGroupContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<MediaGroupContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<MediaGroupContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<MediaGroupContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVisualMediaGroup( suspend fun BehaviourContext.onVisualMediaGroup(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
additionalFilter: (suspend (ContentMessage<VisualMediaGroupContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<VisualMediaGroupContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<VisualMediaGroupContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VisualMediaGroupContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onAnimation( suspend fun BehaviourContext.onAnimation(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<AnimationContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<AnimationContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<AnimationContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<AnimationContent>>
) = 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 = true,
additionalFilter: (suspend (ContentMessage<AudioContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<AudioContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<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 = true,
additionalFilter: (suspend (ContentMessage<DocumentContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<DocumentContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<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 = true,
additionalFilter: (suspend (ContentMessage<PhotoContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<PhotoContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<PhotoContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<PhotoContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onSticker( suspend fun BehaviourContext.onSticker(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<StickerContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<StickerContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<StickerContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<StickerContent>>
) = 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 = true,
additionalFilter: (suspend (ContentMessage<VideoContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<VideoContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<VideoContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VideoContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVideoNote( suspend fun BehaviourContext.onVideoNote(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<VideoNoteContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<VideoNoteContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<VideoNoteContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VideoNoteContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVoice( suspend fun BehaviourContext.onVoice(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<VoiceContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<VoiceContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<VoiceContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<VoiceContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onInvoice( suspend fun BehaviourContext.onInvoice(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ContentMessage<InvoiceContent>) -> Boolean)? = null, additionalFilter: CommonMessageFilter<InvoiceContent>? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ContentMessage<InvoiceContent>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, CommonMessage<InvoiceContent>>
) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)

View File

@ -10,7 +10,7 @@ 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.extensions.utils.shortcuts.chat import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.ContactContent import dev.inmo.tgbotapi.types.message.content.ContactContent
import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.types.message.content.abstracts.*

View File

@ -5,6 +5,7 @@ Concentration of all TelegramBotAPI libraries:
* [TelegramBotAPI Core](../tgbotapi.core/README.md) * [TelegramBotAPI Core](../tgbotapi.core/README.md)
* [TelegramBotAPI Extensions](../tgbotapi.extensions.api/README.md) * [TelegramBotAPI Extensions](../tgbotapi.extensions.api/README.md)
* [TelegramBotAPI Util Extensions](../tgbotapi.extensions.utils/README.md) * [TelegramBotAPI Util Extensions](../tgbotapi.extensions.utils/README.md)
* [TelegramBotAPI Behaviour Builder Extensions](../tgbotapi.extensions.behaviour_builder/README.md)
## Implementation ## Implementation