mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-18 21:45:06 +00:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56d3628dd3 | |||
| 56d7853f68 | |||
| 0a27d9bf28 | |||
| c74df3960c | |||
| f4b080cb45 | |||
| 350b77f6ff | |||
| 955e14f67c | |||
| ae88b7d94d | |||
| 88c62bd51c | |||
| 705bcbe352 | |||
| ffcc149c40 | |||
| 402d91f9f2 | |||
| c19bccc7d1 | |||
| 2c71377058 | |||
| 12d2c05110 | |||
| ddf46c1afd | |||
| dd0a8b99c7 | |||
| 75fb72936f | |||
| 1a6a010446 | |||
| 4c7bfe99c0 | |||
|
|
1e4b8d405e | ||
| 007112e67a | |||
| a87c21273d | |||
| ff2d1615da | |||
| 08ef146daa | |||
| a404a6c59c | |||
| 1089c716f3 | |||
| 81ad55b19f | |||
| 863c872f35 | |||
| ece6a917ed | |||
| 12248aa702 | |||
| 83ea4f6435 | |||
| 52204d8df1 | |||
| 81b9ccdf6a | |||
| fa74f12505 | |||
| be284c4d96 | |||
| 1769fcacfd | |||
| 4207d89c92 | |||
| 87ee2f280b | |||
| 3d458b2dc6 | |||
| ee1c7c6533 | |||
| 97d122c770 | |||
| 49da0faf45 | |||
| d426cb1210 | |||
| af83ac79e7 | |||
| 602f15c206 | |||
| c2f40534e6 | |||
| 5693d4d808 | |||
| 9fe55aa6ef | |||
| 8f817f1492 | |||
| 0fd146655d | |||
| 94e5f74a90 | |||
| b9bffbb71b | |||
| 5ec5c3bdfd | |||
| a5ed2a82bb | |||
| 1b7dd11e75 | |||
| 8d0307fb7f | |||
| c500f0a281 | |||
| b3abeaa5ae | |||
| 8930a66134 | |||
| 76a2a2ca74 | |||
| 7dff8af460 | |||
| 5261ab1cf0 | |||
| f45c653fca | |||
| 5e03098ca8 | |||
| 2a3d8e6e73 | |||
| 8c3dac7932 | |||
| 83fb7f7bcb | |||
| 459414e7dd | |||
| 508d51f5a9 | |||
| 36f22579b2 | |||
| d3d5f7f2e6 | |||
| 1369680419 | |||
| f6e819be62 | |||
| 553da0a3ee | |||
| bace2724da | |||
| be710612b5 | |||
| ea19c10f41 | |||
| 1b88881c62 | |||
| be62c4fe37 | |||
| d3499cdde1 | |||
| 01d04f9d2b | |||
| d290992e40 | |||
| 867bdb8bd7 | |||
| 5f0a67187f | |||
| d9638849e2 | |||
| 5568720b5b | |||
| c0c591fe08 | |||
| 3c1f8421c9 | |||
| 35b20d102c | |||
| 70e6dc8fc9 | |||
| 4f0de376ab | |||
| 10c52c695c | |||
| 2d2c745527 | |||
| 1238843bde | |||
| 1ebaa1c387 | |||
| b2bc47ec04 | |||
| 514620b2bd | |||
| 054f06e18b | |||
| 00d467d091 | |||
| 6426ed6571 | |||
| fba6707f44 | |||
| 0c2fe6bce7 | |||
| eee9fe439f | |||
| 3547c09383 | |||
| 956f02d26d | |||
| 468fc0a49b | |||
| 441f3cee3d | |||
| 1ea79b9f7f | |||
| 094f88867d | |||
| 85a8a8eedc | |||
| 28fce0b4c1 | |||
| 2f5fdcdca0 | |||
| 21799d7e4a | |||
| ca409db0ee | |||
| 33c8ee0803 | |||
| 0c0ec22348 | |||
| 24bffbbd97 | |||
| a615d1c4fd | |||
| a76b7977b3 | |||
| 6004879aef |
2
.github/workflows/kdocs.yml
vendored
2
.github/workflows/kdocs.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: 11
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./gradlew dokkaHtml
|
run: ./gradlew dokkaHtml
|
||||||
- name: Publish KDocs
|
- name: Publish KDocs
|
||||||
|
|||||||
7
.github/workflows/packages_publishing.yml
vendored
7
.github/workflows/packages_publishing.yml
vendored
@@ -7,10 +7,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: 11
|
||||||
- name: Fix android 31.0.0 dx
|
|
||||||
continue-on-error: true
|
|
||||||
run: cd /usr/local/lib/android/sdk/build-tools/31.0.0/ && mv d8 dx && cd lib && mv d8.jar dx.jar
|
|
||||||
- name: Rewrite version
|
- name: Rewrite version
|
||||||
run: |
|
run: |
|
||||||
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
|
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
|
||||||
@@ -21,7 +18,7 @@ jobs:
|
|||||||
run: ./gradlew build
|
run: ./gradlew build
|
||||||
- name: Publish
|
- name: Publish
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: ./gradlew publishAllPublicationsToGithubPackagesRepository --no-parallel -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication
|
run: ./gradlew publishAllPublicationsToGithubPackagesRepository --no-parallel
|
||||||
env:
|
env:
|
||||||
GITHUBPACKAGES_USER: ${{ github.actor }}
|
GITHUBPACKAGES_USER: ${{ github.actor }}
|
||||||
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
136
CHANGELOG.md
136
CHANGELOG.md
@@ -1,5 +1,141 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 0.38.14
|
||||||
|
|
||||||
|
__This update contains including of [Telegram Bot API 6.0](https://core.telegram.org/bots/api-changelog#april-16-2022)__
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* Constructor of `UnknownInlineKeyboardButton` is not internal and can be created with any `json`
|
||||||
|
* `WebApps`:
|
||||||
|
* Created 🎉
|
||||||
|
|
||||||
|
## 0.38.13
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* Fixes in `mention` creation
|
||||||
|
* Deprecate `StorageFileInfo`
|
||||||
|
* `BehaviourBuilder`:
|
||||||
|
* In the expectations a lot of `on*Message` extensions have been added (like `onContentMessage`). These extensions could be useful when with the `Content` its message info is important
|
||||||
|
|
||||||
|
## 0.38.12
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.17` -> `0.9.19`
|
||||||
|
* `Coroutines`: `1.6.0` -> `1.6.1`
|
||||||
|
* `Core`:
|
||||||
|
* New type `TextedMediaContent` which will unite `TextedInput` and `MediaContent`
|
||||||
|
* `MediaGroupContent` and all subsequent inheritors have been replaced to the package `dev.inmo.tgbotapi.types.message.content.media`
|
||||||
|
* `MediaGroupContent` Now extends `TextedMediaContent` instead of `MediaContent`
|
||||||
|
* Add `reply` functions with the texted content with including of text
|
||||||
|
* `Utils`:
|
||||||
|
* Improve work with retrieving of accumulated updates
|
||||||
|
|
||||||
|
## 0.38.11
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.16` -> `0.9.17`
|
||||||
|
* `Klock`: `2.6.3` -> `2.7.0`
|
||||||
|
* `Core`:
|
||||||
|
* Fixes in `TextSourcesList` creating in from `RawMessageEntities`
|
||||||
|
* Old ways to create keyboards (`matrix` and `row`) have been deprecated
|
||||||
|
* `API`:
|
||||||
|
* Add ability to `reply` with `Poll`
|
||||||
|
* Add ability to `reply` with any `MessageContent`
|
||||||
|
* Add ability to `reply` with any `TelegramMediaFile`
|
||||||
|
|
||||||
|
## 0.38.10
|
||||||
|
|
||||||
|
* `API`:
|
||||||
|
* All `with*Action` extensions got a contracts which declare that `block` will be called once
|
||||||
|
* Add several extensions `TelegramBot#sendPhoto` with `PhotoSize`
|
||||||
|
* Add several extensions `TelegramBot#reply` with `PhotoSize`
|
||||||
|
|
||||||
|
## 0.38.9
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* New function `MessageContent.Companion#serializationModule`
|
||||||
|
* Now it is possible to create `TelegramBot` (`RequestsExecutor`) with several bots under the hood and opportunity
|
||||||
|
for bots requests load balancing or fault-fix via sending of the requests via another bot
|
||||||
|
* `API`:
|
||||||
|
* Add replies which will use another message as a source for reply (`copyMessage`)
|
||||||
|
|
||||||
|
## 0.38.8
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.12` -> `0.9.16`
|
||||||
|
* `Klock`: `2.6.2` -> `2.6.3`
|
||||||
|
* `Ktor`: `1.6.7` -> `1.6.8`
|
||||||
|
* `BehaviourBuilder`:
|
||||||
|
* Fixes in `onMediaGroup` and dependent functions
|
||||||
|
* Add several new extensions for `SimpleFilter`:
|
||||||
|
* `SimpleFilter#listAll`
|
||||||
|
* `SimpleFilter#listAny`
|
||||||
|
* `SimpleFilter#listNone`
|
||||||
|
|
||||||
|
## 0.38.7
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.9` -> `0.9.12`
|
||||||
|
* `Klock`: `2.5.2` -> `2.6.2`
|
||||||
|
* `Core`:
|
||||||
|
* `SimplePollOption#votes` now is `0` by default
|
||||||
|
* New function `PollOption.Companion#simple`
|
||||||
|
|
||||||
|
## 0.38.6
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.6` -> `0.9.9`
|
||||||
|
* `Klock`: `2.4.13` -> `2.5.2`
|
||||||
|
* `Core`:
|
||||||
|
* New member of `MentionTextSource` - `username`
|
||||||
|
|
||||||
|
## 0.38.5
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.5` -> `0.9.6`
|
||||||
|
* `Core`:
|
||||||
|
* `Username` got new property `usernameWithoutAt` which will return `username` without leading `@`
|
||||||
|
* `Utils`:
|
||||||
|
* Several new functions for working with deep links:
|
||||||
|
* `makeUsernameDeepLinkPrefix`
|
||||||
|
* `makeTelegramDeepLink`
|
||||||
|
* `makeDeepLink`
|
||||||
|
|
||||||
|
## 0.38.4
|
||||||
|
|
||||||
|
__This update contains including of [Telegram Bot API 5.7](https://core.telegram.org/bots/api-changelog#january-31-2022)__
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* Support of new fields `Sticker`
|
||||||
|
* Support of new fields `StickerSet`
|
||||||
|
* Support of new fields in creating of sticker set and sticker
|
||||||
|
* `Utils`:
|
||||||
|
* Rename `PathedFile` to avoid clash with core file (fix of [#529](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/529))
|
||||||
|
|
||||||
|
## 0.38.3
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.1` -> `0.9.2`
|
||||||
|
* `Klock`: `2.4.10` -> `2.4.12`
|
||||||
|
* `UUID`: `0.3.1` -> `0.4.0`
|
||||||
|
* `API`
|
||||||
|
* New extensions `TelegramBot#send*` for media groups with contents
|
||||||
|
|
||||||
|
## 0.38.2
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.0` -> `0.9.1`
|
||||||
|
* `API`
|
||||||
|
* New extensions `TelegramBot#copyMessages` for media groups
|
||||||
|
|
||||||
## 0.38.1
|
## 0.38.1
|
||||||
|
|
||||||
* `Core`:
|
* `Core`:
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -1,8 +1,8 @@
|
|||||||
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#december-30-2021)
|
# TelegramBotAPI [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#april-16-2022)
|
||||||
|
|
||||||
| [](https://github.com/KotlinBy/awesome-kotlin) [](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [](https://forms.gle/2Hex2ynbHWHhi1KY7) [](https://t.me/InMoTelegramBotAPI) |
|
| [](https://github.com/KotlinBy/awesome-kotlin) [](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) [](https://t.me/InMoTelegramBotAPI) |
|
||||||
|:---:|
|
|:---:|
|
||||||
| [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
| [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) [](https://tgbotapi.inmo.dev/index.html) [](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
||||||
|
|
||||||
Hello! This is a set of libraries for working with Telegram Bot API.
|
Hello! This is a set of libraries for working with Telegram Bot API.
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ Other configuration examples:
|
|||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
val bot = telegramBot(TOKEN)
|
val bot = telegramBot(TOKEN)
|
||||||
|
|
||||||
bot.buildBehaviour {
|
bot.buildBehaviourWithLongPolling {
|
||||||
println(getMe())
|
println(getMe())
|
||||||
|
|
||||||
onCommand("start") {
|
onCommand("start") {
|
||||||
@@ -69,7 +69,7 @@ and maybe some updates it got after launch)
|
|||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
val bot = telegramBot(TOKEN)
|
val bot = telegramBot(TOKEN)
|
||||||
|
|
||||||
bot.buildBehaviour {
|
bot.buildBehaviourWithLongPolling {
|
||||||
println(getMe())
|
println(getMe())
|
||||||
|
|
||||||
val nameReplyMarkup = ReplyKeyboardMarkup(
|
val nameReplyMarkup = ReplyKeyboardMarkup(
|
||||||
|
|||||||
@@ -40,11 +40,17 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib')
|
implementation kotlin('stdlib')
|
||||||
|
|
||||||
rootProject.subprojects.forEach {
|
api project(":tgbotapi.core")
|
||||||
if (it != project) {
|
api project(":tgbotapi.api")
|
||||||
api it
|
api project(":tgbotapi.utils")
|
||||||
}
|
api project(":tgbotapi.behaviour_builder")
|
||||||
}
|
api project(":tgbotapi.behaviour_builder.fsm")
|
||||||
|
api project(":tgbotapi")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsMain {
|
||||||
|
dependencies {
|
||||||
|
api project(":tgbotapi.webapps")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1 @@
|
|||||||
dokka_version=1.6.0
|
|
||||||
|
|
||||||
org.gradle.jvmargs=-Xmx1024m
|
org.gradle.jvmargs=-Xmx1024m
|
||||||
|
|||||||
@@ -6,18 +6,20 @@ kotlin.incremental=true
|
|||||||
kotlin.incremental.js=true
|
kotlin.incremental.js=true
|
||||||
|
|
||||||
kotlin_version=1.6.10
|
kotlin_version=1.6.10
|
||||||
kotlin_coroutines_version=1.6.0
|
kotlin_coroutines_version=1.6.1
|
||||||
kotlin_serialisation_runtime_version=1.3.2
|
kotlin_serialisation_runtime_version=1.3.2
|
||||||
klock_version=2.4.10
|
klock_version=2.7.0
|
||||||
uuid_version=0.3.1
|
uuid_version=0.4.0
|
||||||
ktor_version=1.6.7
|
ktor_version=1.6.8
|
||||||
|
|
||||||
|
micro_utils_version=0.9.20
|
||||||
micro_utils_version=0.9.0
|
|
||||||
|
|
||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
library_group=dev.inmo
|
|
||||||
library_version=0.38.1
|
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
dokka_version=1.6.10
|
||||||
|
|
||||||
|
library_group=dev.inmo
|
||||||
|
library_version=0.38.14
|
||||||
|
|
||||||
|
github_release_plugin_version=2.3.7
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ publishing {
|
|||||||
artifact javadocsJar
|
artifact javadocsJar
|
||||||
|
|
||||||
pom {
|
pom {
|
||||||
description = "This project just include all subproject of TelegramBotAPI"
|
description = "${project.description}"
|
||||||
name = "Telegram Bot API"
|
name = "${project.name}"
|
||||||
url = "https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI"
|
url = "https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI"
|
||||||
|
|
||||||
scm {
|
scm {
|
||||||
1
publish.kpsb
Normal file
1
publish.kpsb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"${project.description}","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
||||||
97
readmes/exceptions_handling.md
Normal file
97
readmes/exceptions_handling.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# Exceptions handling
|
||||||
|
|
||||||
|
Unfortunatelly, exceptions handling in this library is a bit difficult in some places, but that have at least two reasons: flexibility and usability.
|
||||||
|
|
||||||
|
## "In place" handling
|
||||||
|
|
||||||
|
In case you know, where exceptions are happening, you may use several tools for exceptions catching:
|
||||||
|
|
||||||
|
* Catching with result
|
||||||
|
* Catching with callback
|
||||||
|
|
||||||
|
### Catching with result
|
||||||
|
|
||||||
|
If you prefer to receive `Result` objects instead of some weird callbacks, you may use the next syntax:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
safelyWithResult {
|
||||||
|
// do something
|
||||||
|
}.onSuccess { // will be called if everything is right
|
||||||
|
// handle success
|
||||||
|
}.onFailure { // will be called if something went wrong
|
||||||
|
// handle error
|
||||||
|
it.printStackTrace()
|
||||||
|
}.getOrThrow() // will return value or throw exception
|
||||||
|
```
|
||||||
|
|
||||||
|
### Catching with callback
|
||||||
|
|
||||||
|
Also there is more simple (in some cases) way to handle exceptions with callbacks:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
safely(
|
||||||
|
{
|
||||||
|
// handle error
|
||||||
|
it.printStackTrace()
|
||||||
|
null // return value
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bonus: different types of handling
|
||||||
|
|
||||||
|
There are two types of handling:
|
||||||
|
|
||||||
|
* Just safely - when you are using something to obviously retrieve value or throw exception. When handling callback has been skipped, it will throw exception by default. For example:
|
||||||
|
```kotlin
|
||||||
|
safely(
|
||||||
|
{
|
||||||
|
it.printStackTrace()
|
||||||
|
"error"
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
error("Hi :)") // emulate exception throwing
|
||||||
|
"ok"
|
||||||
|
} // result will be with type String
|
||||||
|
```
|
||||||
|
* Safely without exceptions - almost the same as `safely`, but this type by default allow to return nullable value (when exception was thrown) instead of just throwing (as with `safely`):
|
||||||
|
```kotlin
|
||||||
|
safelyWithouExceptions {
|
||||||
|
// do something
|
||||||
|
} // will returns nullable result type
|
||||||
|
```
|
||||||
|
|
||||||
|
## Global exceptions handling
|
||||||
|
|
||||||
|
The most simple way to configure exceptions handling is to change `CoroutineContext` when you are creating your `CoroutineScope` for bot processing:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val bot = telegramBot("TOKEN")
|
||||||
|
|
||||||
|
bot.buildBehaviour (
|
||||||
|
scope = scope,
|
||||||
|
defaultExceptionsHandler = {
|
||||||
|
it.printStackTrace()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val bot = telegramBotWithBehaviour (
|
||||||
|
"TOKEN",
|
||||||
|
scope = scope,
|
||||||
|
defaultExceptionsHandler = {
|
||||||
|
it.printStackTrace()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we have used `ContextSafelyExceptionHandler` class. It will pass default handling of exceptions and will call the block in most cases when something inside of your bot logic has thrown exception.
|
||||||
@@ -21,4 +21,5 @@ include ":tgbotapi.extensions.utils"
|
|||||||
include ":tgbotapi.extensions.behaviour_builder"
|
include ":tgbotapi.extensions.behaviour_builder"
|
||||||
include ":tgbotapi.extensions.behaviour_builder.fsm"
|
include ":tgbotapi.extensions.behaviour_builder.fsm"
|
||||||
include ":tgbotapi"
|
include ":tgbotapi"
|
||||||
|
include ":tgbotapi.webapps"
|
||||||
include ":docs"
|
include ":docs"
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ plugins {
|
|||||||
|
|
||||||
project.version = "$library_version"
|
project.version = "$library_version"
|
||||||
project.group = "$library_group"
|
project.group = "$library_group"
|
||||||
|
project.description = "API extensions with \"Telegram Bot API\"-like extensions for TelegramBot and RequestsExecutor"
|
||||||
|
|
||||||
apply from: "publish.gradle"
|
apply from: "../publish.gradle"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
apply plugin: 'maven-publish'
|
|
||||||
|
|
||||||
task javadocsJar(type: Jar) {
|
|
||||||
classifier = 'javadoc'
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications.all {
|
|
||||||
artifact javadocsJar
|
|
||||||
|
|
||||||
pom {
|
|
||||||
description = "API extensions which provide work with RequestsExecutor of TelegramBotAPI almost like it is described in original Telegram Bot API reference"
|
|
||||||
name = "Telegram Bot API Extensions for API"
|
|
||||||
url = "https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-api"
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "GithubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
|
||||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "sonatype"
|
|
||||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
|
||||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
|
||||||
apply plugin: 'signing'
|
|
||||||
|
|
||||||
signing {
|
|
||||||
useGpgCmd()
|
|
||||||
|
|
||||||
sign publishing.publications
|
|
||||||
}
|
|
||||||
|
|
||||||
task signAll {
|
|
||||||
tasks.withType(Sign).forEach {
|
|
||||||
dependsOn(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"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 Extensions for API","description":"API extensions which provide work with RequestsExecutor of TelegramBotAPI almost like it is described in original Telegram Bot API reference","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-api","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
|
||||||
@@ -13,7 +13,7 @@ import io.ktor.client.engine.*
|
|||||||
*/
|
*/
|
||||||
fun telegramBot(
|
fun telegramBot(
|
||||||
urlsKeeper: TelegramAPIUrlsKeeper,
|
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
client: HttpClient
|
client: HttpClient = HttpClient()
|
||||||
): TelegramBot = telegramBot(urlsKeeper) {
|
): TelegramBot = telegramBot(urlsKeeper) {
|
||||||
this.client = client
|
this.client = client
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ inline fun telegramBot(
|
|||||||
inline fun telegramBot(
|
inline fun telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
client: HttpClient
|
client: HttpClient = HttpClient()
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client)
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.answers
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.answers.AnswerWebAppQuery
|
||||||
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
||||||
|
import dev.inmo.tgbotapi.types.WebAppQueryId
|
||||||
|
|
||||||
|
suspend fun TelegramBot.answerWebAppQuery(
|
||||||
|
webAppQueryId: WebAppQueryId,
|
||||||
|
result: InlineQueryResult
|
||||||
|
) = execute(AnswerWebAppQuery(webAppQueryId, result))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.answer(
|
||||||
|
webAppQueryId: WebAppQueryId,
|
||||||
|
result: InlineQueryResult
|
||||||
|
) = execute(AnswerWebAppQuery(webAppQueryId, result))
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.bot
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.ClearMyDefaultAdministratorRights
|
||||||
|
import dev.inmo.tgbotapi.types.ChatAdministratorRightsImpl
|
||||||
|
|
||||||
|
suspend fun TelegramBot.clearMyDefaultAdministratorRights(
|
||||||
|
forChannels: Boolean? = null
|
||||||
|
) = execute(ClearMyDefaultAdministratorRights(forChannels))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.clearMyDefaultAdministratorRightsForChannels() = clearMyDefaultAdministratorRights(forChannels = true)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.clearMyDefaultAdministratorRightsForGroupsAndSupergroups() = clearMyDefaultAdministratorRights(forChannels = false)
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.bot
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.GetMyDefaultAdministratorRights
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getMyDefaultAdministratorRights(
|
||||||
|
forChannels: Boolean? = null
|
||||||
|
) = execute(GetMyDefaultAdministratorRights(forChannels))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getMyDefaultAdministratorRightsForChannels() = getMyDefaultAdministratorRights(forChannels = true)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getMyDefaultAdministratorRightsForGroupsAndSupergroups() = getMyDefaultAdministratorRights(forChannels = false)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.bot
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.bot.SetMyDefaultAdministratorRights
|
||||||
|
import dev.inmo.tgbotapi.types.ChatAdministratorRightsImpl
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setMyDefaultAdministratorRights(
|
||||||
|
rights: ChatAdministratorRightsImpl,
|
||||||
|
forChannels: Boolean? = null
|
||||||
|
) = execute(SetMyDefaultAdministratorRights(rights, forChannels))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setMyDefaultAdministratorRightsForChannels(
|
||||||
|
rights: ChatAdministratorRightsImpl
|
||||||
|
) = setMyDefaultAdministratorRights(rights, forChannels = true)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setMyDefaultAdministratorRightsForGroupsAndSupergroups(
|
||||||
|
rights: ChatAdministratorRightsImpl
|
||||||
|
) = setMyDefaultAdministratorRights(rights, forChannels = false)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.chat.get
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.chat.get.GetChatMenuButton
|
||||||
|
import dev.inmo.tgbotapi.requests.chat.modify.*
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.chat.abstracts.PrivateChat
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getChatMenuButton(
|
||||||
|
chatId: ChatId
|
||||||
|
) = execute(GetChatMenuButton(chatId))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getChatMenuButton(
|
||||||
|
chat: PrivateChat
|
||||||
|
) = getChatMenuButton(chat.id)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.chat.get
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.chat.get.GetDefaultChatMenuButton
|
||||||
|
import dev.inmo.tgbotapi.requests.chat.modify.SetDefaultChatMenuButton
|
||||||
|
import dev.inmo.tgbotapi.types.MenuButton
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getDefaultChatMenuButton() = execute(GetDefaultChatMenuButton)
|
||||||
@@ -18,7 +18,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers: Boolean? = null,
|
canRestrictMembers: Boolean? = null,
|
||||||
canPinMessages: Boolean? = null,
|
canPinMessages: Boolean? = null,
|
||||||
canPromoteMembers: Boolean? = null,
|
canPromoteMembers: Boolean? = null,
|
||||||
canManageVoiceChats: Boolean? = null,
|
canManageVideoChats: Boolean? = null,
|
||||||
canManageChat: Boolean?
|
canManageChat: Boolean?
|
||||||
) = execute(
|
) = execute(
|
||||||
PromoteChatMember(
|
PromoteChatMember(
|
||||||
@@ -34,7 +34,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers,
|
canRestrictMembers,
|
||||||
canPinMessages,
|
canPinMessages,
|
||||||
canPromoteMembers,
|
canPromoteMembers,
|
||||||
canManageVoiceChats,
|
canManageVideoChats,
|
||||||
canManageChat
|
canManageChat
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -52,7 +52,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers: Boolean? = null,
|
canRestrictMembers: Boolean? = null,
|
||||||
canPinMessages: Boolean? = null,
|
canPinMessages: Boolean? = null,
|
||||||
canPromoteMembers: Boolean? = null,
|
canPromoteMembers: Boolean? = null,
|
||||||
canManageVoiceChats: Boolean? = null,
|
canManageVideoChats: Boolean? = null,
|
||||||
canManageChat: Boolean? = null
|
canManageChat: Boolean? = null
|
||||||
) = promoteChatMember(
|
) = promoteChatMember(
|
||||||
chat.id,
|
chat.id,
|
||||||
@@ -67,7 +67,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers,
|
canRestrictMembers,
|
||||||
canPinMessages,
|
canPinMessages,
|
||||||
canPromoteMembers,
|
canPromoteMembers,
|
||||||
canManageVoiceChats,
|
canManageVideoChats,
|
||||||
canManageChat
|
canManageChat
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers: Boolean? = null,
|
canRestrictMembers: Boolean? = null,
|
||||||
canPinMessages: Boolean? = null,
|
canPinMessages: Boolean? = null,
|
||||||
canPromoteMembers: Boolean? = null,
|
canPromoteMembers: Boolean? = null,
|
||||||
canManageVoiceChats: Boolean? = null,
|
canManageVideoChats: Boolean? = null,
|
||||||
canManageChat: Boolean? = null
|
canManageChat: Boolean? = null
|
||||||
) = promoteChatMember(
|
) = promoteChatMember(
|
||||||
chatId,
|
chatId,
|
||||||
@@ -99,7 +99,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers,
|
canRestrictMembers,
|
||||||
canPinMessages,
|
canPinMessages,
|
||||||
canPromoteMembers,
|
canPromoteMembers,
|
||||||
canManageVoiceChats,
|
canManageVideoChats,
|
||||||
canManageChat
|
canManageChat
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers: Boolean? = null,
|
canRestrictMembers: Boolean? = null,
|
||||||
canPinMessages: Boolean? = null,
|
canPinMessages: Boolean? = null,
|
||||||
canPromoteMembers: Boolean? = null,
|
canPromoteMembers: Boolean? = null,
|
||||||
canManageVoiceChats: Boolean? = null,
|
canManageVideoChats: Boolean? = null,
|
||||||
canManageChat: Boolean? = null
|
canManageChat: Boolean? = null
|
||||||
) = promoteChatMember(
|
) = promoteChatMember(
|
||||||
chat.id,
|
chat.id,
|
||||||
@@ -131,6 +131,6 @@ suspend fun TelegramBot.promoteChatMember(
|
|||||||
canRestrictMembers,
|
canRestrictMembers,
|
||||||
canPinMessages,
|
canPinMessages,
|
||||||
canPromoteMembers,
|
canPromoteMembers,
|
||||||
canManageVoiceChats,
|
canManageVideoChats,
|
||||||
canManageChat
|
canManageChat
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.chat.modify
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.chat.modify.*
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.chat.abstracts.PrivateChat
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setChatMenuButton(
|
||||||
|
chatId: ChatId,
|
||||||
|
menuButton: MenuButton
|
||||||
|
) = execute(SetChatMenuButton(chatId, menuButton))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setChatMenuButton(
|
||||||
|
chat: PrivateChat,
|
||||||
|
menuButton: MenuButton
|
||||||
|
) = setChatMenuButton(chat.id, menuButton)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.chat.modify
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.chat.modify.SetDefaultChatMenuButton
|
||||||
|
import dev.inmo.tgbotapi.types.MenuButton
|
||||||
|
|
||||||
|
suspend fun TelegramBot.setDefaultChatMenuButton(
|
||||||
|
menuButton: MenuButton
|
||||||
|
) = execute(SetDefaultChatMenuButton(menuButton))
|
||||||
@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.extensions.api.get
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.get.GetStickerSet
|
import dev.inmo.tgbotapi.requests.get.GetStickerSet
|
||||||
import dev.inmo.tgbotapi.types.files.Sticker
|
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
||||||
|
|
||||||
suspend fun TelegramBot.getStickerSet(
|
suspend fun TelegramBot.getStickerSet(
|
||||||
name: String
|
name: String
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.send
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup
|
||||||
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
|
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
||||||
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChatId: ChatIdentifier,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
): List<MediaGroupMessage<MediaGroupContent>> {
|
||||||
|
val first = messages.first().content.toMediaGroupMemberInputMedia().let {
|
||||||
|
if (text != null) {
|
||||||
|
when (it) {
|
||||||
|
is InputMediaAudio -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
is InputMediaDocument -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
is InputMediaPhoto -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
is InputMediaVideo -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendMediaGroup(
|
||||||
|
toChatId,
|
||||||
|
listOf(first) + messages.drop(1).map {
|
||||||
|
it.content.toMediaGroupMemberInputMedia()
|
||||||
|
},
|
||||||
|
disableNotification,
|
||||||
|
protectContent,
|
||||||
|
replyToMessageId,
|
||||||
|
allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, messages, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: ChatIdentifier,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat, update.data, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, update, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChatId: ChatIdentifier,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
): List<MediaGroupMessage<MediaGroupContent>> {
|
||||||
|
val first = messages.first().content.toMediaGroupMemberInputMedia().let {
|
||||||
|
when (it) {
|
||||||
|
is InputMediaAudio -> InputMediaAudio(it.file, entities, it.duration, it.performer, it.title, it.thumb)
|
||||||
|
is InputMediaDocument -> InputMediaDocument(it.file, entities, it.thumb, it.disableContentTypeDetection)
|
||||||
|
is InputMediaPhoto -> InputMediaPhoto(it.file, entities)
|
||||||
|
is InputMediaVideo -> InputMediaVideo(it.file, entities, it.width, it.height, it.duration, it.thumb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendMediaGroup(
|
||||||
|
toChatId,
|
||||||
|
listOf(first) + messages.drop(1).map {
|
||||||
|
it.content.toMediaGroupMemberInputMedia()
|
||||||
|
},
|
||||||
|
disableNotification,
|
||||||
|
protectContent,
|
||||||
|
replyToMessageId,
|
||||||
|
allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, messages, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: ChatIdentifier,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat, update.data, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, update, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
@@ -10,15 +10,22 @@ import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
|||||||
import dev.inmo.tgbotapi.requests.send.media.rawSendingMediaGroupsWarning
|
import dev.inmo.tgbotapi.requests.send.media.rawSendingMediaGroupsWarning
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
|
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.dice.DiceAnimationType
|
import dev.inmo.tgbotapi.types.dice.DiceAnimationType
|
||||||
import dev.inmo.tgbotapi.types.files.*
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
|
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
||||||
|
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
||||||
import dev.inmo.tgbotapi.types.games.Game
|
import dev.inmo.tgbotapi.types.games.Game
|
||||||
import dev.inmo.tgbotapi.types.location.StaticLocation
|
import dev.inmo.tgbotapi.types.location.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
||||||
import dev.inmo.tgbotapi.types.payments.abstracts.Currency
|
import dev.inmo.tgbotapi.types.payments.abstracts.Currency
|
||||||
import dev.inmo.tgbotapi.types.polls.*
|
import dev.inmo.tgbotapi.types.polls.*
|
||||||
@@ -116,6 +123,7 @@ suspend inline fun TelegramBot.reply(
|
|||||||
longitude: Double,
|
longitude: Double,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(
|
) = sendLocation(
|
||||||
to.chat,
|
to.chat,
|
||||||
@@ -123,6 +131,7 @@ suspend inline fun TelegramBot.reply(
|
|||||||
longitude,
|
longitude,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
protectContent,
|
protectContent,
|
||||||
|
allowSendingWithoutReply,
|
||||||
to.messageId,
|
to.messageId,
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
@@ -136,12 +145,14 @@ suspend inline fun TelegramBot.reply(
|
|||||||
location: StaticLocation,
|
location: StaticLocation,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(
|
) = sendLocation(
|
||||||
to.chat,
|
to.chat,
|
||||||
location,
|
location,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
protectContent,
|
protectContent,
|
||||||
|
allowSendingWithoutReply,
|
||||||
to.messageId,
|
to.messageId,
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
@@ -569,6 +580,17 @@ suspend inline fun TelegramBot.reply(
|
|||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendPhoto(to.chat, photo, text, parseMode, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
) = sendPhoto(to.chat, photo, text, parseMode, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
photoSize: PhotoSize,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = sendPhoto(to.chat, photoSize, text, parseMode, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
|
||||||
suspend inline fun TelegramBot.replyWithPhoto(
|
suspend inline fun TelegramBot.replyWithPhoto(
|
||||||
to: Message,
|
to: Message,
|
||||||
@@ -590,6 +612,16 @@ suspend inline fun TelegramBot.reply(
|
|||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendPhoto(to.chat, photo, entities, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
) = sendPhoto(to.chat, photo, entities, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
photoSize: PhotoSize,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = sendPhoto(to.chat, photoSize, entities, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
|
||||||
// Sticker
|
// Sticker
|
||||||
|
|
||||||
@@ -863,3 +895,329 @@ suspend inline fun TelegramBot.reply(
|
|||||||
allowSendingWithoutReply: Boolean? = null,
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendQuizPoll(to.chat, isClosed, quizPoll, question, options, correctOptionId, isAnonymous, entities, closeInfo, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
) = sendQuizPoll(to.chat, isClosed, quizPoll, question, options, correctOptionId, isAnonymous, entities, closeInfo, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
poll: Poll,
|
||||||
|
isClosed: Boolean = false,
|
||||||
|
question: String = poll.question,
|
||||||
|
options: List<String> = poll.options.map { it.text },
|
||||||
|
isAnonymous: Boolean = poll.isAnonymous,
|
||||||
|
closeInfo: ScheduledCloseInfo? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = when (poll) {
|
||||||
|
is RegularPoll -> reply(
|
||||||
|
to = to,
|
||||||
|
poll = poll,
|
||||||
|
isClosed = isClosed,
|
||||||
|
question = question,
|
||||||
|
options = options,
|
||||||
|
isAnonymous = isAnonymous,
|
||||||
|
allowMultipleAnswers = isAnonymous,
|
||||||
|
closeInfo = closeInfo,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is UnknownPollType -> error("Unable to send poll with unknown type ($poll)")
|
||||||
|
is QuizPoll -> reply(
|
||||||
|
to = to,
|
||||||
|
quizPoll = poll,
|
||||||
|
entities = poll.textSources,
|
||||||
|
isClosed = isClosed,
|
||||||
|
question = question,
|
||||||
|
options = options,
|
||||||
|
isAnonymous = isAnonymous,
|
||||||
|
closeInfo = closeInfo,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
fromChatId: ChatIdentifier,
|
||||||
|
messageId: MessageIdentifier,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = copyMessage(fromChatId, to.chat.id, messageId, text, parseMode, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
fromChat: Chat,
|
||||||
|
messageId: MessageIdentifier,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = reply(to, fromChat.id, messageId, text, parseMode, disableNotification, protectContent, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
copy: Message,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = reply(to, copy.chat.id, copy.messageId, text, parseMode, disableNotification, protectContent, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
content: MessageContent,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) {
|
||||||
|
execute(
|
||||||
|
content.createResend(
|
||||||
|
to.chat.id,
|
||||||
|
disableNotification,
|
||||||
|
protectContent,
|
||||||
|
to.messageId,
|
||||||
|
allowSendingWithoutReply,
|
||||||
|
replyMarkup
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
mediaFile: TelegramMediaFile,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) {
|
||||||
|
when (mediaFile) {
|
||||||
|
is AudioFile -> reply(
|
||||||
|
to = to,
|
||||||
|
audio = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is AnimationFile -> reply(
|
||||||
|
to = to,
|
||||||
|
animation = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is VoiceFile -> reply(
|
||||||
|
to = to,
|
||||||
|
voice = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is VideoFile -> reply(
|
||||||
|
to = to,
|
||||||
|
video = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is VideoNoteFile -> reply(
|
||||||
|
to = to,
|
||||||
|
videoNote = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is DocumentFile -> reply(
|
||||||
|
to = to,
|
||||||
|
document = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is Sticker -> reply(
|
||||||
|
to = to,
|
||||||
|
sticker = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is PhotoSize -> reply(
|
||||||
|
to = to,
|
||||||
|
photoSize = mediaFile,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
else -> reply(
|
||||||
|
to = to,
|
||||||
|
document = mediaFile.asDocumentFile(),
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
content: TextedMediaContent,
|
||||||
|
text: String?,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) {
|
||||||
|
when (content) {
|
||||||
|
is VoiceContent -> reply(
|
||||||
|
to = to,
|
||||||
|
voice = content.media,
|
||||||
|
text = text,
|
||||||
|
parseMode = parseMode,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is AudioMediaGroupContent -> reply(
|
||||||
|
to = to,
|
||||||
|
audio = content.media,
|
||||||
|
text = text,
|
||||||
|
parseMode = parseMode,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is PhotoContent -> reply(
|
||||||
|
to = to,
|
||||||
|
photoSize = content.media,
|
||||||
|
text = text,
|
||||||
|
parseMode = parseMode,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is VideoContent -> reply(
|
||||||
|
to = to,
|
||||||
|
video = content.media,
|
||||||
|
text = text,
|
||||||
|
parseMode = parseMode,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is AnimationContent -> reply(
|
||||||
|
to = to,
|
||||||
|
animation = content.media,
|
||||||
|
text = text,
|
||||||
|
parseMode = parseMode,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
else -> reply(
|
||||||
|
to = to,
|
||||||
|
document = content.media.asDocumentFile(),
|
||||||
|
text = text,
|
||||||
|
parseMode = parseMode,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun TelegramBot.reply(
|
||||||
|
to: Message,
|
||||||
|
content: TextedMediaContent,
|
||||||
|
entities: List<TextSource>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) {
|
||||||
|
when (content) {
|
||||||
|
is VoiceContent -> reply(
|
||||||
|
to = to,
|
||||||
|
voice = content.media,
|
||||||
|
entities = entities,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is AudioMediaGroupContent -> reply(
|
||||||
|
to = to,
|
||||||
|
audio = content.media,
|
||||||
|
entities = entities,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is PhotoContent -> reply(
|
||||||
|
to = to,
|
||||||
|
photoSize = content.media,
|
||||||
|
entities = entities,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is VideoContent -> reply(
|
||||||
|
to = to,
|
||||||
|
video = content.media,
|
||||||
|
entities = entities,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
is AnimationContent -> reply(
|
||||||
|
to = to,
|
||||||
|
animation = content.media,
|
||||||
|
entities = entities,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
else -> reply(
|
||||||
|
to = to,
|
||||||
|
document = content.media.asDocumentFile(),
|
||||||
|
entities = entities,
|
||||||
|
disableNotification = disableNotification,
|
||||||
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
|
replyMarkup = replyMarkup
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,15 +8,20 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import dev.inmo.tgbotapi.types.actions.*
|
import dev.inmo.tgbotapi.types.actions.*
|
||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import kotlin.contracts.*
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
private const val refreshTime: MilliSeconds = (botActionActualityTime - 1) * 1000L
|
private const val refreshTime: MilliSeconds = (botActionActualityTime - 1) * 1000L
|
||||||
typealias TelegramBotActionCallback<T> = suspend TelegramBot.() -> T
|
typealias TelegramBotActionCallback<T> = suspend TelegramBot.() -> T
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withAction(
|
suspend fun <T> TelegramBot.withAction(
|
||||||
actionRequest: SendAction,
|
actionRequest: SendAction,
|
||||||
block: TelegramBotActionCallback<T>
|
block: TelegramBotActionCallback<T>
|
||||||
): T {
|
): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
val botActionJob = CoroutineScope(coroutineContext).launch {
|
val botActionJob = CoroutineScope(coroutineContext).launch {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
delay(refreshTime)
|
delay(refreshTime)
|
||||||
@@ -30,46 +35,190 @@ suspend fun <T> TelegramBot.withAction(
|
|||||||
return result.getOrThrow()
|
return result.getOrThrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withAction(
|
suspend fun <T> TelegramBot.withAction(
|
||||||
chatId: ChatId,
|
chatId: ChatId,
|
||||||
action: BotAction,
|
action: BotAction,
|
||||||
block: TelegramBotActionCallback<T>
|
block: TelegramBotActionCallback<T>
|
||||||
) = withAction(
|
): T {
|
||||||
SendAction(chatId, action),
|
contract {
|
||||||
block
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
)
|
}
|
||||||
|
return withAction(
|
||||||
|
SendAction(chatId, action),
|
||||||
|
block
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withAction(
|
suspend fun <T> TelegramBot.withAction(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
action: BotAction,
|
action: BotAction,
|
||||||
block: TelegramBotActionCallback<T>
|
block: TelegramBotActionCallback<T>
|
||||||
) = withAction(
|
): T {
|
||||||
chat.id,
|
contract {
|
||||||
action,
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
block
|
}
|
||||||
)
|
return withAction(
|
||||||
|
chat.id,
|
||||||
|
action,
|
||||||
|
block
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun <T> TelegramBot.withTypingAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, TypingAction, block)
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadPhotoAction, block)
|
suspend fun <T> TelegramBot.withTypingAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
suspend fun <T> TelegramBot.withRecordVideoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, RecordVideoAction, block)
|
contract {
|
||||||
suspend fun <T> TelegramBot.withUploadVideoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadVideoAction, block)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
suspend fun <T> TelegramBot.withRecordVoiceAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, RecordVoiceAction, block)
|
}
|
||||||
suspend fun <T> TelegramBot.withUploadVoiceAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadVoiceAction, block)
|
return withAction(chatId, TypingAction, block)
|
||||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadDocumentAction, block)
|
}
|
||||||
suspend fun <T> TelegramBot.withFindLocationAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, FindLocationAction, block)
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, RecordVideoNoteAction, block)
|
suspend fun <T> TelegramBot.withUploadPhotoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, UploadVideoNoteAction, block)
|
contract {
|
||||||
suspend fun <T> TelegramBot.withChooseStickerAction(chatId: ChatId, block: TelegramBotActionCallback<T>) = withAction(chatId, ChooseStickerAction, block)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, UploadPhotoAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withRecordVideoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, RecordVideoAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadVideoAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, UploadVideoAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withRecordVoiceAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, RecordVoiceAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadVoiceAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, UploadVoiceAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadDocumentAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, UploadDocumentAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withFindLocationAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, FindLocationAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, RecordVideoNoteAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, UploadVideoNoteAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withChooseStickerAction(chatId: ChatId, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chatId, ChooseStickerAction, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend fun <T> TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, TypingAction, block)
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withUploadPhotoAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadPhotoAction, block)
|
suspend fun <T> TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
suspend fun <T> TelegramBot.withRecordVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, RecordVideoAction, block)
|
contract {
|
||||||
suspend fun <T> TelegramBot.withUploadVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadVideoAction, block)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
suspend fun <T> TelegramBot.withRecordVoiceAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, RecordVoiceAction, block)
|
}
|
||||||
suspend fun <T> TelegramBot.withUploadVoiceAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadVoiceAction, block)
|
return withAction(chat, TypingAction, block)
|
||||||
suspend fun <T> TelegramBot.withUploadDocumentAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadDocumentAction, block)
|
}
|
||||||
suspend fun <T> TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, FindLocationAction, block)
|
@OptIn(ExperimentalContracts::class)
|
||||||
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, RecordVideoNoteAction, block)
|
suspend fun <T> TelegramBot.withUploadPhotoAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, UploadVideoNoteAction, block)
|
contract {
|
||||||
suspend fun <T> TelegramBot.withChooseStickerAction(chat: Chat, block: TelegramBotActionCallback<T>) = withAction(chat, ChooseStickerAction, block)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, UploadPhotoAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withRecordVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, RecordVideoAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadVideoAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, UploadVideoAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withRecordVoiceAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, RecordVoiceAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadVoiceAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, UploadVoiceAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadDocumentAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, UploadDocumentAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, FindLocationAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, RecordVideoNoteAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, UploadVideoNoteAction, block)
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend fun <T> TelegramBot.withChooseStickerAction(chat: Chat, block: TelegramBotActionCallback<T>) : T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return withAction(chat, ChooseStickerAction, block)
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
longitude: Double,
|
longitude: Double,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = execute(
|
) = execute(
|
||||||
@@ -27,6 +28,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
longitude,
|
longitude,
|
||||||
disableNotification = disableNotification,
|
disableNotification = disableNotification,
|
||||||
protectContent = protectContent,
|
protectContent = protectContent,
|
||||||
|
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||||
replyToMessageId = replyToMessageId,
|
replyToMessageId = replyToMessageId,
|
||||||
replyMarkup = replyMarkup
|
replyMarkup = replyMarkup
|
||||||
)
|
)
|
||||||
@@ -41,6 +43,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
location: StaticLocation,
|
location: StaticLocation,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(
|
) = sendLocation(
|
||||||
@@ -49,6 +52,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
location.longitude,
|
location.longitude,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
protectContent,
|
protectContent,
|
||||||
|
allowSendingWithoutReply,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
@@ -63,6 +67,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
longitude: Double,
|
longitude: Double,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(
|
) = sendLocation(
|
||||||
@@ -71,6 +76,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
longitude,
|
longitude,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
protectContent,
|
protectContent,
|
||||||
|
allowSendingWithoutReply,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
@@ -84,6 +90,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
location: StaticLocation,
|
location: StaticLocation,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(
|
) = sendLocation(
|
||||||
@@ -92,6 +99,7 @@ suspend fun TelegramBot.sendLocation(
|
|||||||
location.longitude,
|
location.longitude,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
protectContent,
|
protectContent,
|
||||||
|
allowSendingWithoutReply,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
@@ -106,9 +114,10 @@ suspend fun TelegramBot.sendStaticLocation(
|
|||||||
longitude: Double,
|
longitude: Double,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(chatId, latitude, longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
) = sendLocation(chatId, latitude, longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
@@ -119,9 +128,10 @@ suspend fun TelegramBot.sendStaticLocation(
|
|||||||
location: StaticLocation,
|
location: StaticLocation,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(chatId, location.latitude, location.longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
) = sendLocation(chatId, location.latitude, location.longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
@@ -133,9 +143,10 @@ suspend fun TelegramBot.sendStaticLocation(
|
|||||||
longitude: Double,
|
longitude: Double,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(chat.id, latitude, longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
) = sendLocation(chat.id, latitude, longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
@@ -146,6 +157,7 @@ suspend fun TelegramBot.sendStaticLocation(
|
|||||||
location: StaticLocation,
|
location: StaticLocation,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
protectContent: Boolean = false,
|
protectContent: Boolean = false,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendLocation(chat.id, location.latitude, location.longitude, disableNotification, protectContent, replyToMessageId, replyMarkup)
|
) = sendLocation(chat.id, location.latitude, location.longitude, disableNotification, protectContent, allowSendingWithoutReply, replyToMessageId, replyMarkup)
|
||||||
|
|||||||
@@ -6,8 +6,12 @@ import dev.inmo.tgbotapi.types.ChatIdentifier
|
|||||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SendMediaGroup
|
* @see SendMediaGroup
|
||||||
@@ -41,6 +45,38 @@ suspend fun TelegramBot.sendMediaGroup(
|
|||||||
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendMediaGroup
|
||||||
|
*/
|
||||||
|
@RiskFeature(rawSendingMediaGroupsWarning)
|
||||||
|
@JvmName("sendMedaGroupByContent")
|
||||||
|
suspend fun TelegramBot.sendMediaGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<MediaGroupContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendMediaGroup(
|
||||||
|
chatId, media.map { it.toMediaGroupMemberInputMedia() }, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendMediaGroup
|
||||||
|
*/
|
||||||
|
@RiskFeature(rawSendingMediaGroupsWarning)
|
||||||
|
@JvmName("sendMedaGroupByContent")
|
||||||
|
suspend fun TelegramBot.sendMediaGroup(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<MediaGroupContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendMediaGroup(
|
||||||
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SendPlaylist
|
* @see SendPlaylist
|
||||||
*/
|
*/
|
||||||
@@ -71,6 +107,36 @@ suspend fun TelegramBot.sendPlaylist(
|
|||||||
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendPlaylist
|
||||||
|
*/
|
||||||
|
@JvmName("sendPlaylistByContent")
|
||||||
|
suspend fun TelegramBot.sendPlaylist(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<AudioContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendPlaylist(
|
||||||
|
chatId, media.map { it.toMediaGroupMemberInputMedia() }, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendPlaylist
|
||||||
|
*/
|
||||||
|
@JvmName("sendPlaylistByContent")
|
||||||
|
suspend fun TelegramBot.sendPlaylist(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<AudioContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendPlaylist(
|
||||||
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SendDocumentsGroup
|
* @see SendDocumentsGroup
|
||||||
*/
|
*/
|
||||||
@@ -101,6 +167,36 @@ suspend fun TelegramBot.sendDocumentsGroup(
|
|||||||
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendDocumentsGroup
|
||||||
|
*/
|
||||||
|
@JvmName("sendDocumentsByContent")
|
||||||
|
suspend fun TelegramBot.sendDocumentsGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<DocumentContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendDocumentsGroup(
|
||||||
|
chatId, media.map { it.toMediaGroupMemberInputMedia() }, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendDocumentsGroup
|
||||||
|
*/
|
||||||
|
@JvmName("sendDocumentsByContent")
|
||||||
|
suspend fun TelegramBot.sendDocumentsGroup(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<DocumentContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendDocumentsGroup(
|
||||||
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SendVisualMediaGroup
|
* @see SendVisualMediaGroup
|
||||||
*/
|
*/
|
||||||
@@ -130,3 +226,33 @@ suspend fun TelegramBot.sendVisualMediaGroup(
|
|||||||
) = sendVisualMediaGroup(
|
) = sendVisualMediaGroup(
|
||||||
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendVisualMediaGroup
|
||||||
|
*/
|
||||||
|
@JvmName("sendVisualMediaGroupByContent")
|
||||||
|
suspend fun TelegramBot.sendVisualMediaGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<VisualMediaGroupContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendVisualMediaGroup(
|
||||||
|
chatId, media.map { it.toMediaGroupMemberInputMedia() }, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendVisualMediaGroup
|
||||||
|
*/
|
||||||
|
@JvmName("sendVisualMediaGroupByContent")
|
||||||
|
suspend fun TelegramBot.sendVisualMediaGroup(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<VisualMediaGroupContent>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = sendVisualMediaGroup(
|
||||||
|
chat.id, media, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ import dev.inmo.tgbotapi.types.MessageIdentifier
|
|||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.files.Photo
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.files.biggest
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
@@ -88,6 +87,38 @@ suspend fun TelegramBot.sendPhoto(
|
|||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendPhoto(chat.id, photo, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
) = sendPhoto(chat.id, photo, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
|
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendPhoto(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
photoSize: PhotoSize,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = sendPhoto(chatId, photoSize.fileId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
|
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendPhoto(
|
||||||
|
chat: Chat,
|
||||||
|
photoSize: PhotoSize,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = sendPhoto(chat.id, photoSize, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
@@ -159,3 +190,33 @@ suspend inline fun TelegramBot.sendPhoto(
|
|||||||
allowSendingWithoutReply: Boolean? = null,
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = sendPhoto(chat.id, photo, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
) = sendPhoto(chat.id, photo, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
|
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.sendPhoto(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
photoSize: PhotoSize,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = sendPhoto(chatId, photoSize.fileId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
|
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.sendPhoto(
|
||||||
|
chat: Chat,
|
||||||
|
photoSize: PhotoSize,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null,
|
||||||
|
replyMarkup: KeyboardMarkup? = null
|
||||||
|
) = sendPhoto(chat.id, photoSize, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.ChatIdentifier
|
|||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.files.Sticker
|
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.stickers
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.AddVideoStickerToSet
|
||||||
|
import dev.inmo.tgbotapi.types.CommonUser
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
|
import dev.inmo.tgbotapi.types.stickers.StickerSet
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
userId: UserId,
|
||||||
|
stickerSetName: String,
|
||||||
|
sticker: FileId,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = execute(
|
||||||
|
AddVideoStickerToSet(userId, stickerSetName, sticker, emojis, maskPosition)
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
userId: UserId,
|
||||||
|
stickerSetName: String,
|
||||||
|
sticker: MultipartFile,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = execute(
|
||||||
|
AddVideoStickerToSet(userId, stickerSetName, sticker, emojis, maskPosition)
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
user: CommonUser,
|
||||||
|
stickerSetName: String,
|
||||||
|
sticker: FileId,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = addVideoStickerToSet(
|
||||||
|
user.id, stickerSetName, sticker, emojis, maskPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
user: CommonUser,
|
||||||
|
stickerSetName: String,
|
||||||
|
sticker: MultipartFile,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = addVideoStickerToSet(
|
||||||
|
user.id, stickerSetName, sticker, emojis, maskPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
userId: UserId,
|
||||||
|
stickerSet: StickerSet,
|
||||||
|
sticker: FileId,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = addVideoStickerToSet(
|
||||||
|
userId, stickerSet.name, sticker, emojis, maskPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
userId: UserId,
|
||||||
|
stickerSet: StickerSet,
|
||||||
|
sticker: MultipartFile,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = addVideoStickerToSet(
|
||||||
|
userId, stickerSet.name, sticker, emojis, maskPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
user: CommonUser,
|
||||||
|
stickerSet: StickerSet,
|
||||||
|
sticker: FileId,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = addVideoStickerToSet(
|
||||||
|
user.id, stickerSet.name, sticker, emojis, maskPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.addVideoStickerToSet(
|
||||||
|
user: CommonUser,
|
||||||
|
stickerSet: StickerSet,
|
||||||
|
sticker: MultipartFile,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = addVideoStickerToSet(
|
||||||
|
user.id, stickerSet.name, sticker, emojis, maskPosition
|
||||||
|
)
|
||||||
@@ -11,44 +11,48 @@ import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
|||||||
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: FileId,
|
sticker: FileId,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = execute(
|
) = execute(
|
||||||
CreateNewAnimatedStickerSet(userId, name, sticker, emojis, containsMasks, maskPosition)
|
CreateNewAnimatedStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: MultipartFile,
|
sticker: MultipartFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = execute(
|
) = execute(
|
||||||
CreateNewAnimatedStickerSet(userId, name, sticker, emojis, containsMasks, maskPosition)
|
CreateNewAnimatedStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
||||||
user: CommonUser,
|
user: CommonUser,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: FileId,
|
sticker: FileId,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = createNewAnimatedStickerSet(
|
) = createNewAnimatedStickerSet(
|
||||||
user.id, name, sticker, emojis, containsMasks, maskPosition
|
user.id, name, title, sticker, emojis, containsMasks, maskPosition
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
suspend fun TelegramBot.createNewAnimatedStickerSet(
|
||||||
user: CommonUser,
|
user: CommonUser,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: MultipartFile,
|
sticker: MultipartFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = createNewAnimatedStickerSet(
|
) = createNewAnimatedStickerSet(
|
||||||
user.id, name, sticker, emojis, containsMasks, maskPosition
|
user.id, name, title, sticker, emojis, containsMasks, maskPosition
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,44 +11,48 @@ import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
|||||||
suspend fun TelegramBot.createNewStaticStickerSet(
|
suspend fun TelegramBot.createNewStaticStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: FileId,
|
sticker: FileId,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = execute(
|
) = execute(
|
||||||
CreateNewStaticStickerSet(userId, name, sticker, emojis, containsMasks, maskPosition)
|
CreateNewStaticStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun TelegramBot.createNewStaticStickerSet(
|
suspend fun TelegramBot.createNewStaticStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: MultipartFile,
|
sticker: MultipartFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = execute(
|
) = execute(
|
||||||
CreateNewStaticStickerSet(userId, name, sticker, emojis, containsMasks, maskPosition)
|
CreateNewStaticStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
suspend fun TelegramBot.createNewStaticStickerSet(
|
suspend fun TelegramBot.createNewStaticStickerSet(
|
||||||
user: CommonUser,
|
user: CommonUser,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: FileId,
|
sticker: FileId,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = createNewStaticStickerSet(
|
) = createNewStaticStickerSet(
|
||||||
user.id, name, sticker, emojis, containsMasks, maskPosition
|
user.id, name, title, sticker, emojis, containsMasks, maskPosition
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun TelegramBot.createNewStaticStickerSet(
|
suspend fun TelegramBot.createNewStaticStickerSet(
|
||||||
user: CommonUser,
|
user: CommonUser,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: MultipartFile,
|
sticker: MultipartFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
) = createNewStaticStickerSet(
|
) = createNewStaticStickerSet(
|
||||||
user.id, name, sticker, emojis, containsMasks, maskPosition
|
user.id, name, title, sticker, emojis, containsMasks, maskPosition
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.stickers
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.CreateNewVideoStickerSet
|
||||||
|
import dev.inmo.tgbotapi.types.CommonUser
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
|
|
||||||
|
suspend fun TelegramBot.createNewVideoStickerSet(
|
||||||
|
userId: UserId,
|
||||||
|
name: String,
|
||||||
|
title: String,
|
||||||
|
sticker: FileId,
|
||||||
|
emojis: String,
|
||||||
|
containsMasks: Boolean? = null,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = execute(
|
||||||
|
CreateNewVideoStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.createNewVideoStickerSet(
|
||||||
|
userId: UserId,
|
||||||
|
name: String,
|
||||||
|
title: String,
|
||||||
|
sticker: MultipartFile,
|
||||||
|
emojis: String,
|
||||||
|
containsMasks: Boolean? = null,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = execute(
|
||||||
|
CreateNewVideoStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun TelegramBot.createNewVideoStickerSet(
|
||||||
|
user: CommonUser,
|
||||||
|
name: String,
|
||||||
|
title: String,
|
||||||
|
sticker: FileId,
|
||||||
|
emojis: String,
|
||||||
|
containsMasks: Boolean? = null,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = createNewVideoStickerSet(
|
||||||
|
user.id, name, title, sticker, emojis, containsMasks, maskPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.createNewVideoStickerSet(
|
||||||
|
user: CommonUser,
|
||||||
|
name: String,
|
||||||
|
title: String,
|
||||||
|
sticker: MultipartFile,
|
||||||
|
emojis: String,
|
||||||
|
containsMasks: Boolean? = null,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
) = createNewVideoStickerSet(
|
||||||
|
user.id, name, title, sticker, emojis, containsMasks, maskPosition
|
||||||
|
)
|
||||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.stickers
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.stickers.DeleteStickerFromSet
|
import dev.inmo.tgbotapi.requests.stickers.DeleteStickerFromSet
|
||||||
import dev.inmo.tgbotapi.types.files.Sticker
|
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
||||||
|
|
||||||
suspend fun TelegramBot.deleteStickerFromSet(
|
suspend fun TelegramBot.deleteStickerFromSet(
|
||||||
sticker: FileId
|
sticker: FileId
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.stickers
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.stickers.SetStickerPositionInSet
|
import dev.inmo.tgbotapi.requests.stickers.SetStickerPositionInSet
|
||||||
import dev.inmo.tgbotapi.types.files.Sticker
|
import dev.inmo.tgbotapi.types.files.sticker.Sticker
|
||||||
|
|
||||||
suspend fun TelegramBot.setStickerPositionInSet(
|
suspend fun TelegramBot.setStickerPositionInSet(
|
||||||
sticker: FileId,
|
sticker: FileId,
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ plugins {
|
|||||||
|
|
||||||
project.version = "$library_version"
|
project.version = "$library_version"
|
||||||
project.group = "$library_group"
|
project.group = "$library_group"
|
||||||
|
project.description = "Behaviour Builder extension with built-in FSM"
|
||||||
|
|
||||||
apply from: "publish.gradle"
|
apply from: "../publish.gradle"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
apply plugin: 'maven-publish'
|
|
||||||
|
|
||||||
task javadocsJar(type: Jar) {
|
|
||||||
classifier = 'javadoc'
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications.all {
|
|
||||||
artifact javadocsJar
|
|
||||||
|
|
||||||
pom {
|
|
||||||
description = "FSM extension for dev.inmo:tgbotapi.extensions.behaviour_builder.fsm"
|
|
||||||
name = "Telegram Bot Behaviour Builder FSM Extensions"
|
|
||||||
url = "https://insanusmokrassar.github.io/TelegramBotAPI/tgbotapi.extensions.behaviour_builder"
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "GithubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
|
||||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "sonatype"
|
|
||||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
|
||||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
|
||||||
apply plugin: 'signing'
|
|
||||||
|
|
||||||
signing {
|
|
||||||
useGpgCmd()
|
|
||||||
|
|
||||||
sign publishing.publications
|
|
||||||
}
|
|
||||||
|
|
||||||
task signAll {
|
|
||||||
tasks.withType(Sign).forEach {
|
|
||||||
dependsOn(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot Behaviour Builder FSM Extensions","description":"FSM extension for dev.inmo:tgbotapi.extensions.behaviour_builder.fsm","url":"https://insanusmokrassar.github.io/TelegramBotAPI/tgbotapi.extensions.behaviour_builder","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
|
||||||
@@ -17,8 +17,9 @@ plugins {
|
|||||||
|
|
||||||
project.version = "$library_version"
|
project.version = "$library_version"
|
||||||
project.group = "$library_group"
|
project.group = "$library_group"
|
||||||
|
project.description = "Behaviour Builder DSL"
|
||||||
|
|
||||||
apply from: "publish.gradle"
|
apply from: "../publish.gradle"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{"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":"This 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","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
apply plugin: 'maven-publish'
|
|
||||||
|
|
||||||
task javadocsJar(type: Jar) {
|
|
||||||
classifier = 'javadoc'
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications.all {
|
|
||||||
artifact javadocsJar
|
|
||||||
|
|
||||||
pom {
|
|
||||||
description = "This 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 {
|
|
||||||
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "GithubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
|
||||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "sonatype"
|
|
||||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
|
||||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
|
||||||
apply plugin: 'signing'
|
|
||||||
|
|
||||||
signing {
|
|
||||||
useGpgCmd()
|
|
||||||
|
|
||||||
sign publishing.publications
|
|
||||||
}
|
|
||||||
|
|
||||||
task signAll {
|
|
||||||
tasks.withType(Sign).forEach {
|
|
||||||
dependsOn(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"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":"This 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"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
|
||||||
@@ -11,16 +11,19 @@ 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.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
||||||
|
|
||||||
private suspend fun <O> BehaviourContext.waitCommonMessage(
|
private suspend fun <O> BehaviourContext.waitCommonContent(
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
includeMediaGroups: Boolean = true,
|
includeMediaGroups: Boolean = true,
|
||||||
@@ -74,7 +77,7 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
|
|||||||
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
noinline filter: SimpleFilter<CommonMessage<T>>? = null,
|
noinline filter: SimpleFilter<CommonMessage<T>>? = null,
|
||||||
noinline mapper: CommonMessageToContentMapper<T>? = null
|
noinline mapper: CommonMessageToContentMapper<T>? = null
|
||||||
) : List<T> = waitCommonMessage<T>(
|
) : List<T> = waitCommonContent<T>(
|
||||||
count,
|
count,
|
||||||
initRequest,
|
initRequest,
|
||||||
includeMediaGroups,
|
includeMediaGroups,
|
||||||
@@ -87,7 +90,8 @@ private suspend inline fun <reified T : MessageContent> BehaviourContext.waitCon
|
|||||||
contentConverter(mapper)
|
contentConverter(mapper)
|
||||||
).toList()
|
).toList()
|
||||||
|
|
||||||
suspend fun BehaviourContext.waitContentMessage(
|
|
||||||
|
suspend fun BehaviourContext.waitContent(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
@@ -198,6 +202,14 @@ suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
|||||||
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
||||||
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
|
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
|
||||||
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitTextedMediaContent(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
|
||||||
|
mapper: CommonMessageToContentMapper<TextedMediaContent>? = null
|
||||||
|
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
suspend fun BehaviourContext.waitAnimation(
|
suspend fun BehaviourContext.waitAnimation(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
|||||||
@@ -0,0 +1,281 @@
|
|||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
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.utils.SimpleFilter
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.withContent
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
|
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.content.media.AudioMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||||
|
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.toList
|
||||||
|
|
||||||
|
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
|
||||||
|
|
||||||
|
internal suspend fun <O : MessageContent> BehaviourContext.waitCommonMessage(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
filter: SimpleFilter<CommonMessage<MessageContent>>? = null,
|
||||||
|
mapper: suspend CommonMessage<MessageContent>.() -> CommonMessage<O>?
|
||||||
|
): Flow<CommonMessage<O>> = expectFlow(
|
||||||
|
initRequest,
|
||||||
|
count,
|
||||||
|
errorFactory
|
||||||
|
) {
|
||||||
|
val messages = when (it) {
|
||||||
|
is SentMediaGroupUpdate -> {
|
||||||
|
if (includeMediaGroups) {
|
||||||
|
it.data.map { it as CommonMessage<MessageContent> }
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is BaseSentMessageUpdate -> listOf(it.data)
|
||||||
|
else -> return@expectFlow emptyList()
|
||||||
|
}
|
||||||
|
messages.mapNotNull { message ->
|
||||||
|
val asCommonMessage = message as CommonMessage<MessageContent>
|
||||||
|
if (filter == null || filter(asCommonMessage)) {
|
||||||
|
asCommonMessage.mapper()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified T : MessageContent> contentMessageConverter(
|
||||||
|
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
|
||||||
|
): suspend CommonMessage<MessageContent>.() -> CommonMessage<T>? = mapper ?.let {
|
||||||
|
{
|
||||||
|
if (content is T) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val message = (this as CommonMessage<T>)
|
||||||
|
safelyWithoutExceptions { mapper(message) }
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
if (content is T) this as CommonMessage<T> else null
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend inline fun <reified T : MessageContent> BehaviourContext.waitContentMessage(
|
||||||
|
count: Int = 1,
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
noinline errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
noinline filter: SimpleFilter<CommonMessage<T>>? = null,
|
||||||
|
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
|
||||||
|
) : List<CommonMessage<T>> = waitCommonMessage<T>(
|
||||||
|
count,
|
||||||
|
initRequest,
|
||||||
|
includeMediaGroups,
|
||||||
|
errorFactory,
|
||||||
|
filter ?.let {
|
||||||
|
{
|
||||||
|
it.withContent<T>() ?.let { filter(it) } == true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentMessageConverter(mapper)
|
||||||
|
).toList()
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<MessageContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<MessageContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitContactMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<ContactContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<ContactContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitDiceMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<DiceContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<DiceContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitGameMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<GameContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<GameContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitLocationMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<LocationContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<LocationContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitLiveLocationMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<LiveLocationContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<LiveLocationContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitStaticLocationMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<StaticLocationContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<StaticLocationContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitPollMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<PollContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<PollContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitTextMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<TextContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<TextContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVenueMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<VenueContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<VenueContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<AudioMediaGroupContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<AudioMediaGroupContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<DocumentMediaGroupContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<DocumentMediaGroupContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitMediaMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = false,
|
||||||
|
filter: SimpleFilter<CommonMessage<MediaContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<MediaContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<MediaGroupContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<MediaGroupContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<VisualMediaGroupContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitTextedMediaContentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<TextedMediaContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitAnimationMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<AnimationContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<AnimationContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitAudioMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = false,
|
||||||
|
filter: SimpleFilter<CommonMessage<AudioContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<AudioContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitDocumentMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = false,
|
||||||
|
filter: SimpleFilter<CommonMessage<DocumentContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<DocumentContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitPhotoMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = false,
|
||||||
|
filter: SimpleFilter<CommonMessage<PhotoContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<PhotoContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitStickerMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<StickerContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<StickerContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVideoMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = false,
|
||||||
|
filter: SimpleFilter<CommonMessage<VideoContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<VideoContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVideoNoteMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<VideoNoteContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<VideoNoteContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVoiceMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<VoiceContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<VoiceContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitInvoiceMessage(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<CommonMessage<InvoiceContent>>? = null,
|
||||||
|
mapper: CommonMessageToCommonMessageMapper<InvoiceContent>? = null
|
||||||
|
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
|
||||||
@@ -12,6 +12,10 @@ 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.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
|
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
@@ -173,6 +177,14 @@ suspend fun BehaviourContext.waitEditedVisualMediaGroupContent(
|
|||||||
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
|
||||||
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
|
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
|
||||||
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitEditedTextedMediaContent(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
includeMediaGroups: Boolean = true,
|
||||||
|
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
|
||||||
|
mapper: CommonMessageToContentMapper<TextedMediaContent>? = null
|
||||||
|
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
|
||||||
suspend fun BehaviourContext.waitEditedAnimation(
|
suspend fun BehaviourContext.waitEditedAnimation(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.requests.abstracts.Request
|
|||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.PrivateEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
@@ -89,33 +90,66 @@ suspend fun BehaviourContext.waitChatEvents(
|
|||||||
mapper: EventMessageToEventMapper<ChatEvent>? = null
|
mapper: EventMessageToEventMapper<ChatEvent>? = null
|
||||||
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun BehaviourContext.waitVoiceChatEvents(
|
suspend fun BehaviourContext.waitVoiceChatEvents(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: SimpleFilter<ChatEventMessage<VoiceChatEvent>>? = null,
|
filter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
|
||||||
mapper: EventMessageToEventMapper<VoiceChatEvent>? = null
|
mapper: EventMessageToEventMapper<VideoChatEvent>? = null
|
||||||
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun BehaviourContext.waitVoiceChatStartedEvents(
|
suspend fun BehaviourContext.waitVoiceChatStartedEvents(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: SimpleFilter<ChatEventMessage<VoiceChatStarted>>? = null,
|
filter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
|
||||||
mapper: EventMessageToEventMapper<VoiceChatStarted>? = null
|
mapper: EventMessageToEventMapper<VideoChatStarted>? = null
|
||||||
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun BehaviourContext.waitVoiceChatEndedEvents(
|
suspend fun BehaviourContext.waitVoiceChatEndedEvents(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: SimpleFilter<ChatEventMessage<VoiceChatEnded>>? = null,
|
filter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
|
||||||
mapper: EventMessageToEventMapper<VoiceChatEnded>? = null
|
mapper: EventMessageToEventMapper<VideoChatEnded>? = null
|
||||||
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents(
|
suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents(
|
||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null },
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
count: Int = 1,
|
count: Int = 1,
|
||||||
filter: SimpleFilter<ChatEventMessage<VoiceChatParticipantsInvited>>? = null,
|
filter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
|
||||||
mapper: EventMessageToEventMapper<VoiceChatParticipantsInvited>? = null
|
mapper: EventMessageToEventMapper<VideoChatParticipantsInvited>? = null
|
||||||
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitVideoChatEvents(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
|
||||||
|
mapper: EventMessageToEventMapper<VideoChatEvent>? = null
|
||||||
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVideoChatStartedEvents(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
|
||||||
|
mapper: EventMessageToEventMapper<VideoChatStarted>? = null
|
||||||
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVideoChatEndedEvents(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
|
||||||
|
mapper: EventMessageToEventMapper<VideoChatEnded>? = null
|
||||||
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitVideoChatParticipantsInvitedEvents(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
|
||||||
|
mapper: EventMessageToEventMapper<VideoChatParticipantsInvited>? = null
|
||||||
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
|
||||||
suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents(
|
suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents(
|
||||||
@@ -241,3 +275,10 @@ suspend fun BehaviourContext.waitUserLoggedInEvents(
|
|||||||
filter: SimpleFilter<ChatEventMessage<UserLoggedIn>>? = null,
|
filter: SimpleFilter<ChatEventMessage<UserLoggedIn>>? = null,
|
||||||
mapper: EventMessageToEventMapper<UserLoggedIn>? = null
|
mapper: EventMessageToEventMapper<UserLoggedIn>? = null
|
||||||
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
|
||||||
|
suspend fun BehaviourContext.waitWebAppDataEvents(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null },
|
||||||
|
count: Int = 1,
|
||||||
|
filter: SimpleFilter<PrivateEventMessage<WebAppData>>? = null,
|
||||||
|
mapper: EventMessageToEventMapper<WebAppData>? = null
|
||||||
|
) = waitEvents(count, initRequest, errorFactory, filter ?.let { { it is PrivateEventMessage && filter(it) } }, mapper)
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
|
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||||
import kotlinx.coroutines.flow.take
|
import kotlinx.coroutines.flow.take
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ 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.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||||
@@ -22,7 +24,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
|
|||||||
typealias CommonMessageFilter<T> = SimpleFilter<CommonMessage<T>>
|
typealias CommonMessageFilter<T> = SimpleFilter<CommonMessage<T>>
|
||||||
inline fun <T : MessageContent> CommonMessageFilter(noinline block: CommonMessageFilter<T>) = block
|
inline fun <T : MessageContent> CommonMessageFilter(noinline block: CommonMessageFilter<T>) = block
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onContent(
|
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onContentMessageWithType(
|
||||||
noinline initialFilter: CommonMessageFilter<T>? = null,
|
noinline initialFilter: CommonMessageFilter<T>? = null,
|
||||||
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = MessageFilterByChat,
|
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = ByChatMessageMarkerFactory,
|
||||||
@@ -55,7 +57,7 @@ suspend fun <BC : BehaviourContext> BC.onContentMessage(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MessageContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MessageContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<MessageContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<MessageContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MessageContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MessageContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -79,7 +81,7 @@ suspend fun <BC : BehaviourContext> BC.onContact(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<ContactContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<ContactContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<ContactContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<ContactContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<ContactContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<ContactContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -103,7 +105,7 @@ suspend fun <BC : BehaviourContext> BC.onDice(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DiceContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DiceContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<DiceContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<DiceContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DiceContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DiceContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -127,7 +129,7 @@ suspend fun <BC : BehaviourContext> BC.onGame(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<GameContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<GameContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<GameContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<GameContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<GameContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<GameContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -151,7 +153,7 @@ suspend fun <BC : BehaviourContext> BC.onLocation(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<LocationContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<LocationContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<LocationContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<LocationContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LocationContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LocationContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -175,7 +177,7 @@ suspend fun <BC : BehaviourContext> BC.onLiveLocation(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<LiveLocationContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<LiveLocationContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<LiveLocationContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<LiveLocationContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LiveLocationContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LiveLocationContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -199,7 +201,7 @@ suspend fun <BC : BehaviourContext> BC.onStaticLocation(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<StaticLocationContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<StaticLocationContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<StaticLocationContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<StaticLocationContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StaticLocationContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StaticLocationContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -223,7 +225,7 @@ suspend fun <BC : BehaviourContext> BC.onPoll(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PollContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PollContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<PollContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<PollContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PollContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PollContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -247,7 +249,7 @@ suspend fun <BC : BehaviourContext> BC.onText(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -271,7 +273,7 @@ suspend fun <BC : BehaviourContext> BC.onVenue(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VenueContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VenueContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<VenueContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<VenueContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VenueContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VenueContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -295,7 +297,7 @@ suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioMediaGroupContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioMediaGroupContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<AudioMediaGroupContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<AudioMediaGroupContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioMediaGroupContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioMediaGroupContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -319,7 +321,31 @@ suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentMediaGroupContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentMediaGroupContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<DocumentMediaGroupContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<DocumentMediaGroupContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentMediaGroupContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentMediaGroupContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
|
initialFilter,
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onTextedMediaContent(
|
||||||
|
initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedMediaContent>, Update> = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextedMediaContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedMediaContent>>
|
||||||
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -343,7 +369,7 @@ suspend fun <BC : BehaviourContext> BC.onMediaCollection(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -367,7 +393,7 @@ suspend fun <BC : BehaviourContext> BC.onMedia(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<MediaContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<MediaContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -391,7 +417,7 @@ suspend fun <BC : BehaviourContext> BC.onAnimation(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -415,7 +441,7 @@ suspend fun <BC : BehaviourContext> BC.onAudio(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -439,7 +465,7 @@ suspend fun <BC : BehaviourContext> BC.onDocument(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -463,7 +489,7 @@ suspend fun <BC : BehaviourContext> BC.onPhoto(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -487,7 +513,7 @@ suspend fun <BC : BehaviourContext> BC.onSticker(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<StickerContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<StickerContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<StickerContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<StickerContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StickerContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StickerContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -511,7 +537,7 @@ suspend fun <BC : BehaviourContext> BC.onVideo(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -535,7 +561,7 @@ suspend fun <BC : BehaviourContext> BC.onVideoNote(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoNoteContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoNoteContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<VideoNoteContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<VideoNoteContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoNoteContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoNoteContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -559,7 +585,7 @@ suspend fun <BC : BehaviourContext> BC.onVoice(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
@@ -583,7 +609,7 @@ suspend fun <BC : BehaviourContext> BC.onInvoice(
|
|||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<InvoiceContent>, Update> = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<InvoiceContent>, Update> = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in CommonMessage<InvoiceContent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in CommonMessage<InvoiceContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<InvoiceContent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<InvoiceContent>>
|
||||||
) = onContent(
|
) = onContentMessageWithType(
|
||||||
initialFilter,
|
initialFilter,
|
||||||
subcontextUpdatesFilter,
|
subcontextUpdatesFilter,
|
||||||
markerFactory,
|
markerFactory,
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ 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.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
|
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
@@ -262,6 +264,30 @@ suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
|
|||||||
scenarioReceiver
|
scenarioReceiver
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onEditedTextedMediaContent(
|
||||||
|
initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedMediaContent>, Update> = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in CommonMessage<TextedMediaContent>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedMediaContent>>
|
||||||
|
)= onEditedContent(
|
||||||
|
initialFilter,
|
||||||
|
subcontextUpdatesFilter,
|
||||||
|
markerFactory,
|
||||||
|
scenarioReceiver
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage
|
|||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
||||||
|
import dev.inmo.tgbotapi.types.message.PrivateEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
@@ -94,11 +95,12 @@ suspend fun <BC : BehaviourContext> BC.onChatEvent(
|
|||||||
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent(
|
suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent(
|
||||||
initialFilter: SimpleFilter<ChatEventMessage<VoiceChatEvent>>? = null,
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatEvent>, Update>? = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEvent>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatEvent>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEvent>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatEvent>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEvent>>
|
||||||
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,11 +115,12 @@ suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent(
|
|||||||
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent(
|
suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent(
|
||||||
initialFilter: SimpleFilter<ChatEventMessage<VoiceChatStarted>>? = null,
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatStarted>, Update>? = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatStarted>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatStarted>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatStarted>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatStarted>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatStarted>>
|
||||||
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,11 +135,12 @@ suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent(
|
|||||||
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent(
|
suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent(
|
||||||
initialFilter: SimpleFilter<ChatEventMessage<VoiceChatEnded>>? = null,
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatEnded>, Update>? = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEnded>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatEnded>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEnded>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatEnded>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEnded>>
|
||||||
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,11 +155,88 @@ suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent(
|
|||||||
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Renamed as Video instead of Voice")
|
||||||
suspend fun <BC : BehaviourContext> BC.onVoiceChatParticipantsInvitedEvent(
|
suspend fun <BC : BehaviourContext> BC.onVoiceChatParticipantsInvitedEvent(
|
||||||
initialFilter: SimpleFilter<ChatEventMessage<VoiceChatParticipantsInvited>>? = null,
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VoiceChatParticipantsInvited>, Update>? = MessageFilterByChat,
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatParticipantsInvited>, Update>? = MessageFilterByChat,
|
||||||
markerFactory: MarkerFactory<in ChatEventMessage<VoiceChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VoiceChatParticipantsInvited>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatParticipantsInvited>>
|
||||||
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onVideoChatEvent(
|
||||||
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEvent>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEvent>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEvent>>
|
||||||
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onVideoChatStartedEvent(
|
||||||
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatStarted>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatStarted>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatStarted>>
|
||||||
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onVideoChatEndedEvent(
|
||||||
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEnded>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEnded>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEnded>>
|
||||||
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onVideoChatParticipantsInvitedEvent(
|
||||||
|
initialFilter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatParticipantsInvited>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatParticipantsInvited>>
|
||||||
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -483,3 +564,30 @@ suspend fun <BC : BehaviourContext> BC.onUserLoggedIn(
|
|||||||
markerFactory: MarkerFactory<in ChatEventMessage<UserLoggedIn>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<UserLoggedIn>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<UserLoggedIn>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<UserLoggedIn>>
|
||||||
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param markerFactory Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onWebAppData(
|
||||||
|
initialFilter: SimpleFilter<PrivateEventMessage<WebAppData>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<WebAppData>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<WebAppData>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PrivateEventMessage<WebAppData>>
|
||||||
|
) = onEvent(
|
||||||
|
initialFilter ?.let { { it is PrivateEventMessage<WebAppData> && initialFilter(it) } },
|
||||||
|
subcontextUpdatesFilter ?.let { { it: ChatEventMessage<WebAppData>, update: Update -> it is PrivateEventMessage<WebAppData> && subcontextUpdatesFilter(it, update) } },
|
||||||
|
markerFactory
|
||||||
|
) {
|
||||||
|
if (it is PrivateEventMessage<WebAppData>) {
|
||||||
|
scenarioReceiver(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByC
|
|||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||||
import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate
|
import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
|
import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
import dev.inmo.tgbotapi.utils.PreviewFeature
|
import dev.inmo.tgbotapi.utils.PreviewFeature
|
||||||
|
|
||||||
@@ -22,7 +24,11 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MediaGroupConten
|
|||||||
markerFactory: MarkerFactory<in List<MediaGroupMessage<T>>, Any> = ByChatMediaGroupMarkerFactory,
|
markerFactory: MarkerFactory<in List<MediaGroupMessage<T>>, Any> = ByChatMediaGroupMarkerFactory,
|
||||||
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, List<MediaGroupMessage<T>>>
|
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, List<MediaGroupMessage<T>>>
|
||||||
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
|
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
|
||||||
(it.asSentMediaGroupUpdate() ?.data ?.takeIf { it.all { it is T } } as? List<MediaGroupMessage<T>>) ?.let(::listOfNotNull)
|
(it.asSentMediaGroupUpdate() ?.data ?.takeIf { messages ->
|
||||||
|
messages.all { message ->
|
||||||
|
message.content is T
|
||||||
|
}
|
||||||
|
} as? List<MediaGroupMessage<T>>) ?.let(::listOfNotNull)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,6 +4,27 @@ typealias SimpleFilter<T> = suspend (T) -> Boolean
|
|||||||
|
|
||||||
inline fun <T> SimpleFilter(noinline block: SimpleFilter<T>) = block
|
inline fun <T> SimpleFilter(noinline block: SimpleFilter<T>) = block
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return [SimpleFilter] which will return true in case when all the items in incoming data passed [this] filter
|
||||||
|
*/
|
||||||
|
fun <T> SimpleFilter<T>.listAll() = SimpleFilter<Iterable<T>> {
|
||||||
|
it.all { this@listAll(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return [SimpleFilter] which will return true in case when there is any item in incoming data passed [this] filter
|
||||||
|
*/
|
||||||
|
fun <T> SimpleFilter<T>.listAny() = SimpleFilter<Iterable<T>> {
|
||||||
|
it.any { this@listAny(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return [SimpleFilter] which will return true in case when there is no any item in incoming data passed [this] filter
|
||||||
|
*/
|
||||||
|
fun <T> SimpleFilter<T>.listNone() = SimpleFilter<Iterable<T>> {
|
||||||
|
it.none { this@listNone(it) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes an AND (&&) operation between [this] and [other]
|
* Makes an AND (&&) operation between [this] and [other]
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ plugins {
|
|||||||
|
|
||||||
project.version = "$library_version"
|
project.version = "$library_version"
|
||||||
project.group = "$library_group"
|
project.group = "$library_group"
|
||||||
|
project.description = "Core part of tgbotapi with all (and only) required functionality for working with Telegram Bot API"
|
||||||
|
|
||||||
apply from: "publish.gradle"
|
apply from: "../publish.gradle"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
apply plugin: 'maven-publish'
|
|
||||||
|
|
||||||
task javadocsJar(type: Jar) {
|
|
||||||
classifier = 'javadoc'
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications.all {
|
|
||||||
artifact javadocsJar
|
|
||||||
|
|
||||||
pom {
|
|
||||||
description = "Library for Object-Oriented and type-safe work with Telegram Bot API"
|
|
||||||
name = "Telegram Bot API Core"
|
|
||||||
url = "https://insanusmokrassar.github.io/TelegramBotAPI"
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "GithubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
|
||||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
|
||||||
maven {
|
|
||||||
name = "sonatype"
|
|
||||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
|
||||||
credentials {
|
|
||||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
|
||||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
|
||||||
apply plugin: 'signing'
|
|
||||||
|
|
||||||
signing {
|
|
||||||
useGpgCmd()
|
|
||||||
|
|
||||||
sign publishing.publications
|
|
||||||
}
|
|
||||||
|
|
||||||
task signAll {
|
|
||||||
tasks.withType(Sign).forEach {
|
|
||||||
dependsOn(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"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 Core","description":"Library for Object-Oriented and type-safe work with Telegram Bot API","url":"https://insanusmokrassar.github.io/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
|
||||||
@@ -2,6 +2,6 @@ package dev.inmo.tgbotapi.CommonAbstracts.types
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
|
||||||
interface ChatRequest {
|
interface ChatRequest : OptionalChatRequest {
|
||||||
val chatId: ChatIdentifier
|
override val chatId: ChatIdentifier
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.inmo.tgbotapi.CommonAbstracts.types
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
|
||||||
|
interface OptionalChatRequest {
|
||||||
|
val chatId: ChatIdentifier?
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor
|
package dev.inmo.tgbotapi.bot.Ktor
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.common.Optional
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
|||||||
import dev.inmo.tgbotapi.bot.Ktor.base.*
|
import dev.inmo.tgbotapi.bot.Ktor.base.*
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
@@ -15,33 +16,6 @@ import io.ktor.client.features.*
|
|||||||
import io.ktor.client.statement.readText
|
import io.ktor.client.statement.readText
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class KtorRequestsExecutorBuilder(
|
|
||||||
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
|
||||||
) {
|
|
||||||
var client: HttpClient = HttpClient()
|
|
||||||
var callsFactories: List<KtorCallFactory> = emptyList()
|
|
||||||
var excludeDefaultFactories: Boolean = false
|
|
||||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
|
||||||
var jsonFormatter: Json = nonstrictJsonFormat
|
|
||||||
|
|
||||||
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun telegramBot(
|
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
|
||||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
|
||||||
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shortcut for [telegramBot]
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
inline fun telegramBot(
|
|
||||||
token: String,
|
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
|
||||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
|
||||||
|
|
||||||
@RiskFeature
|
@RiskFeature
|
||||||
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
|
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
|
||||||
SimpleRequestCallFactory(),
|
SimpleRequestCallFactory(),
|
||||||
@@ -56,7 +30,8 @@ class KtorRequestsExecutor(
|
|||||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||||
excludeDefaultFactories: Boolean = false,
|
excludeDefaultFactories: Boolean = false,
|
||||||
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
|
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
|
||||||
private val jsonFormatter: Json = nonstrictJsonFormat
|
private val jsonFormatter: Json = nonstrictJsonFormat,
|
||||||
|
private val pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
|
||||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||||
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
||||||
if (!excludeDefaultFactories) {
|
if (!excludeDefaultFactories) {
|
||||||
@@ -73,37 +48,51 @@ class KtorRequestsExecutor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun <T : Any> execute(request: Request<T>): T {
|
override suspend fun <T : Any> execute(request: Request<T>): T {
|
||||||
return safely(
|
return runCatching {
|
||||||
{ e ->
|
safely(
|
||||||
throw if (e is ClientRequestException) {
|
{ e ->
|
||||||
val content = e.response.readText()
|
pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it }
|
||||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
|
||||||
newRequestException(
|
|
||||||
responseObject,
|
|
||||||
content,
|
|
||||||
"Can't get result object from $content"
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
requestsLimiter.limit {
|
|
||||||
var result: T? = null
|
|
||||||
for (potentialFactory in callsFactories) {
|
|
||||||
result = potentialFactory.makeCall(
|
|
||||||
client,
|
|
||||||
telegramAPIUrlsKeeper,
|
|
||||||
request,
|
|
||||||
jsonFormatter
|
|
||||||
)
|
|
||||||
if (result != null) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result ?: error("Can't execute request: $request")
|
throw if (e is ClientRequestException) {
|
||||||
|
val content = e.response.readText()
|
||||||
|
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||||
|
newRequestException(
|
||||||
|
responseObject,
|
||||||
|
content,
|
||||||
|
"Can't get result object from $content"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
e
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
|
||||||
|
requestsLimiter.limit {
|
||||||
|
var result: T? = null
|
||||||
|
lateinit var factoryHandledRequest: KtorCallFactory
|
||||||
|
for (potentialFactory in callsFactories) {
|
||||||
|
pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory)
|
||||||
|
result = potentialFactory.makeCall(
|
||||||
|
client,
|
||||||
|
telegramAPIUrlsKeeper,
|
||||||
|
request,
|
||||||
|
jsonFormatter
|
||||||
|
)
|
||||||
|
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory)
|
||||||
|
if (result != null) {
|
||||||
|
factoryHandledRequest = potentialFactory
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result ?.let {
|
||||||
|
pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories)
|
||||||
|
} ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}.let {
|
||||||
|
pipelineStepsHolder.onRequestReturnResult(it, request, callsFactories)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,3 +100,30 @@ class KtorRequestsExecutor(
|
|||||||
client.close()
|
client.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class KtorRequestsExecutorBuilder(
|
||||||
|
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
||||||
|
) {
|
||||||
|
var client: HttpClient = HttpClient()
|
||||||
|
var callsFactories: List<KtorCallFactory> = emptyList()
|
||||||
|
var excludeDefaultFactories: Boolean = false
|
||||||
|
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
||||||
|
var jsonFormatter: Json = nonstrictJsonFormat
|
||||||
|
|
||||||
|
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun telegramBot(
|
||||||
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||||
|
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for [telegramBot]
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun telegramBot(
|
||||||
|
token: String,
|
||||||
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||||
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
package dev.inmo.tgbotapi.bot.Ktor.base
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
|
import dev.inmo.micro_utils.coroutines.*
|
||||||
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
||||||
import dev.inmo.tgbotapi.requests.DownloadFileStream
|
import dev.inmo.tgbotapi.requests.DownloadFileStream
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
@@ -25,13 +25,16 @@ object DownloadFileChannelRequestCallFactory : KtorCallFactory {
|
|||||||
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
|
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
|
||||||
|
|
||||||
ByteReadChannelAllocator {
|
ByteReadChannelAllocator {
|
||||||
val scope = CoroutineScope(coroutineContext)
|
val scope = CoroutineScope(currentCoroutineContext() + SupervisorJob())
|
||||||
val outChannel = ByteChannel()
|
val outChannel = ByteChannel()
|
||||||
scope.launchSafelyWithoutExceptions {
|
scope.launch {
|
||||||
client.get<HttpStatement>(fullUrl).execute { httpResponse ->
|
runCatchingSafely {
|
||||||
val channel: ByteReadChannel = httpResponse.receive()
|
client.get<HttpStatement>(fullUrl).execute { httpResponse ->
|
||||||
channel.copyAndClose(outChannel)
|
val channel: ByteReadChannel = httpResponse.receive()
|
||||||
|
channel.copyAndClose(outChannel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
scope.cancel()
|
||||||
}
|
}
|
||||||
outChannel
|
outChannel
|
||||||
} as T
|
} as T
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package dev.inmo.tgbotapi.bot.ktor
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
|
||||||
|
interface KtorPipelineStepsHolder {
|
||||||
|
/**
|
||||||
|
* Will be called when any exception will happen due to the [request] handling. If returns value - that value
|
||||||
|
* will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
||||||
|
*/
|
||||||
|
suspend fun <T: Any> onRequestException(
|
||||||
|
request: Request<T>,
|
||||||
|
t: Throwable
|
||||||
|
): T? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will always be called before requests executor will check all [callsFactories] for an opportunity to make call of
|
||||||
|
* [request]
|
||||||
|
*/
|
||||||
|
suspend fun onBeforeSearchCallFactory(
|
||||||
|
request: Request<*>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will always be called before [potentialFactory] will try to make [request]
|
||||||
|
*/
|
||||||
|
suspend fun onBeforeCallFactoryMakeCall(
|
||||||
|
request: Request<*>,
|
||||||
|
potentialFactory: KtorCallFactory
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will always be called after [potentialFactory] has tried to make [request] and got some [result]. If returns
|
||||||
|
* value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
||||||
|
*/
|
||||||
|
suspend fun <T: Any> onAfterCallFactoryMakeCall(
|
||||||
|
result: T?,
|
||||||
|
request: Request<T>,
|
||||||
|
potentialFactory: KtorCallFactory
|
||||||
|
): T? = result
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will be called when [resultCallFactory] is the [KtorCallFactory] from [callsFactories] which has successfully
|
||||||
|
* handled [request] and returned [result]. If returns value - that value will be returned from
|
||||||
|
* [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
||||||
|
*/
|
||||||
|
suspend fun <T: Any> onRequestResultPresented(
|
||||||
|
result: T,
|
||||||
|
request: Request<T>,
|
||||||
|
resultCallFactory: KtorCallFactory,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T? = result
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will be called when there is no [KtorCallFactory] from [callsFactories] which may handle [request]. If returns
|
||||||
|
* value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
||||||
|
*/
|
||||||
|
suspend fun <T: Any> onRequestResultAbsent(
|
||||||
|
request: Request<T>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This step will be called when the [result] has been retrieved (or exception has happened). If returns value -
|
||||||
|
* that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
||||||
|
*/
|
||||||
|
suspend fun <T: Any> onRequestReturnResult(
|
||||||
|
result: Result<T>,
|
||||||
|
request: Request<T>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T = result.getOrThrow()
|
||||||
|
|
||||||
|
companion object : KtorPipelineStepsHolder
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
package dev.inmo.tgbotapi.bot.multiserver
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.Ktor.KtorRequestsExecutorBuilder
|
||||||
|
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
|
||||||
|
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
|
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import kotlin.js.JsName
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type of [RequestsExecutor] (aka [TelegramBot]) has been created to aggregate several bots under the hood and make
|
||||||
|
* requests, for example, with changing of api url
|
||||||
|
*
|
||||||
|
* @param bots Bots which will be used to [execute] [Request]s
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one [execute]. By default, will select next
|
||||||
|
* [TelegramBot] when called (or first when current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [close] method. By default, will close all [bots]
|
||||||
|
*/
|
||||||
|
class SimpleMultiServerRequestsExecutor(
|
||||||
|
private val bots: List<TelegramBot>,
|
||||||
|
private val botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
private val onClose: () -> Unit = {
|
||||||
|
bots.forEach(TelegramBot::close)
|
||||||
|
}
|
||||||
|
) : RequestsExecutor {
|
||||||
|
override suspend fun <T : Any> execute(request: Request<T>): T {
|
||||||
|
var currentBot = bots.botSelector(-1, null)
|
||||||
|
while (currentCoroutineContext().isActive) {
|
||||||
|
val i = bots.indexOf(currentBot)
|
||||||
|
runCatching {
|
||||||
|
currentBot.execute(request)
|
||||||
|
}.onSuccess {
|
||||||
|
return it
|
||||||
|
}.onFailure {
|
||||||
|
currentBot = bots.botSelector(i, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error("Coroutine has been terminated")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* @param keepers Will be used to create result [bots]
|
||||||
|
* @param builder Will be called with each item from [keepers] in process of bots creation
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one [execute]. By default, will select next
|
||||||
|
* [TelegramBot] when called (or first when current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [close] method. By default, will close all [bots]
|
||||||
|
*/
|
||||||
|
@JvmName("createByUrlsKeepers")
|
||||||
|
@JsName("createByUrlsKeepers")
|
||||||
|
inline operator fun invoke(
|
||||||
|
keepers: Iterable<TelegramAPIUrlsKeeper>,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.(TelegramAPIUrlsKeeper) -> Unit = {},
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: ((List<TelegramBot>) -> Unit)? = null
|
||||||
|
): SimpleMultiServerRequestsExecutor {
|
||||||
|
val bots = keepers.map { telegramBot(it) { builder(it) } }
|
||||||
|
return if (onClose == null) {
|
||||||
|
SimpleMultiServerRequestsExecutor(bots, botSelector)
|
||||||
|
} else {
|
||||||
|
SimpleMultiServerRequestsExecutor(bots, botSelector) {
|
||||||
|
onClose(bots)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tokens Will be used to create result [bots]
|
||||||
|
* @param builder Will be called with each item from [tokens] in process of bots creation
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one [execute]. By default, will select next
|
||||||
|
* [TelegramBot] when called (or first when current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [close] method. By default, will close all [bots]
|
||||||
|
*/
|
||||||
|
@JvmName("createByTokens")
|
||||||
|
@JsName("createByTokens")
|
||||||
|
inline operator fun invoke(
|
||||||
|
tokens: Iterable<String>,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.(String) -> Unit = {},
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: ((List<TelegramBot>) -> Unit)? = null
|
||||||
|
): SimpleMultiServerRequestsExecutor {
|
||||||
|
val bots = tokens.map { telegramBot(it) { builder(it) } }
|
||||||
|
return if (onClose == null) {
|
||||||
|
SimpleMultiServerRequestsExecutor(bots, botSelector)
|
||||||
|
} else {
|
||||||
|
SimpleMultiServerRequestsExecutor(bots, botSelector) {
|
||||||
|
onClose(bots)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tokens [Pair]s with first parameter as a token and second parameter api url. Will be used to create
|
||||||
|
* result [bots]
|
||||||
|
* @param builder Will be called with each item from [tokens] in process of bots creation
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one [execute]. By default, will select next
|
||||||
|
* [TelegramBot] when called (or first when current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [close] method. By default, will close all [bots]
|
||||||
|
*/
|
||||||
|
@JvmName("createByTokensAndApiUrls")
|
||||||
|
@JsName("createByTokensAndApiUrls")
|
||||||
|
inline operator fun invoke(
|
||||||
|
tokens: Iterable<Pair<String, String>>,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.(Pair<String, String>) -> Unit = {},
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: ((List<TelegramBot>) -> Unit)? = null
|
||||||
|
): SimpleMultiServerRequestsExecutor {
|
||||||
|
val bots = tokens.map { telegramBot(it.first, it.second) { builder(it) } }
|
||||||
|
return if (onClose == null) {
|
||||||
|
SimpleMultiServerRequestsExecutor(bots, botSelector)
|
||||||
|
} else {
|
||||||
|
SimpleMultiServerRequestsExecutor(bots, botSelector) {
|
||||||
|
onClose(bots)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [SimpleMultiServerRequestsExecutor]
|
||||||
|
*
|
||||||
|
* @param bots Bots which will be used to [SimpleMultiServerRequestsExecutor.execute] [Request]s
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one
|
||||||
|
* [SimpleMultiServerRequestsExecutor.execute]. By default, will select next [TelegramBot] when called (or first when
|
||||||
|
* current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [SimpleMultiServerRequestsExecutor.close] method. By default, will close all [bots]
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun telegramBot(
|
||||||
|
bots: List<TelegramBot>,
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: () -> Unit = {
|
||||||
|
bots.forEach(TelegramBot::close)
|
||||||
|
}
|
||||||
|
): TelegramBot = SimpleMultiServerRequestsExecutor(bots, botSelector, onClose)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param keepers Will be used to create result [SimpleMultiServerRequestsExecutor.bots]
|
||||||
|
* @param builder Will be called with each item from [keepers] in process of bots creation
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one
|
||||||
|
* [SimpleMultiServerRequestsExecutor.execute]. By default, will select next [TelegramBot] when called (or first when
|
||||||
|
* current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [SimpleMultiServerRequestsExecutor.close] method. By default,
|
||||||
|
* will close all [SimpleMultiServerRequestsExecutor.bots]
|
||||||
|
*/
|
||||||
|
@JvmName("telegramBotByApiUrlsKeepers")
|
||||||
|
@JsName("telegramBotByApiUrlsKeepers")
|
||||||
|
inline fun telegramBot(
|
||||||
|
keepers: Iterable<TelegramAPIUrlsKeeper>,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.(TelegramAPIUrlsKeeper) -> Unit = {},
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: ((List<TelegramBot>) -> Unit)? = null
|
||||||
|
): TelegramBot = SimpleMultiServerRequestsExecutor(keepers, builder, botSelector, onClose)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tokens Will be used to create result [SimpleMultiServerRequestsExecutor.bots]
|
||||||
|
* @param builder Will be called with each item from [tokens] in process of bots creation
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one
|
||||||
|
* [SimpleMultiServerRequestsExecutor.execute]. By default, will select next [TelegramBot] when called (or first when
|
||||||
|
* current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [SimpleMultiServerRequestsExecutor.close] method. By default,
|
||||||
|
* will close all [SimpleMultiServerRequestsExecutor.bots]
|
||||||
|
*/
|
||||||
|
@JvmName("telegramBotByTokens")
|
||||||
|
@JsName("telegramBotByTokens")
|
||||||
|
inline fun telegramBot(
|
||||||
|
tokens: Iterable<String>,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.(String) -> Unit = {},
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: ((List<TelegramBot>) -> Unit)? = null
|
||||||
|
): TelegramBot = SimpleMultiServerRequestsExecutor(tokens, builder, botSelector, onClose)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tokens [Pair]s with first parameter as a token and second parameter api url. Will be used to create
|
||||||
|
* result [SimpleMultiServerRequestsExecutor.bots]
|
||||||
|
* @param builder Will be called with each item from [tokens] in process of bots creation
|
||||||
|
* @param botSelector It is strategy by which the bot is selected for the execution. This lambda will receive **-1**
|
||||||
|
* when request execution just started and this call is first in context of one
|
||||||
|
* [SimpleMultiServerRequestsExecutor.execute]. By default, will select next
|
||||||
|
* [TelegramBot] when called (or first when current index is last or -1)
|
||||||
|
* @param onClose This method will be called inside of [SimpleMultiServerRequestsExecutor.close] method. By default,
|
||||||
|
* will close all [SimpleMultiServerRequestsExecutor.bots]
|
||||||
|
*/
|
||||||
|
@JvmName("telegramBotByTokensAndApiUrls")
|
||||||
|
@JsName("telegramBotByTokensAndApiUrls")
|
||||||
|
inline fun telegramBot(
|
||||||
|
tokens: Iterable<Pair<String, String>>,
|
||||||
|
crossinline builder: KtorRequestsExecutorBuilder.(Pair<String, String>) -> Unit = {},
|
||||||
|
noinline botSelector: suspend List<TelegramBot>.(currentBotIndex: Int, t: Throwable?) -> TelegramBot = { i, _ ->
|
||||||
|
getOrElse(i + 1) { first() }
|
||||||
|
},
|
||||||
|
noinline onClose: ((List<TelegramBot>) -> Unit)? = null
|
||||||
|
): TelegramBot = SimpleMultiServerRequestsExecutor(tokens, builder, botSelector, onClose)
|
||||||
@@ -61,9 +61,9 @@ object InputFileSerializer : KSerializer<InputFile> {
|
|||||||
@Serializable(InputFileSerializer::class)
|
@Serializable(InputFileSerializer::class)
|
||||||
data class MultipartFile (
|
data class MultipartFile (
|
||||||
val file: StorageFile,
|
val file: StorageFile,
|
||||||
val filename: String = file.storageFileInfo.fileName
|
val filename: String = file.fileName
|
||||||
) : InputFile() {
|
) : InputFile() {
|
||||||
override val fileId: String = file.storageFileInfo.generateCustomName()
|
override val fileId: String = file.generateCustomName()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.answers
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
||||||
|
import dev.inmo.tgbotapi.types.webapps.query.SentWebAppMessage
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class AnswerWebAppQuery(
|
||||||
|
@SerialName(webAppQueryIdField)
|
||||||
|
val webAppQueryId: WebAppQueryId,
|
||||||
|
@SerialName(resultField)
|
||||||
|
val result: InlineQueryResult
|
||||||
|
) : SimpleRequest<SentWebAppMessage> {
|
||||||
|
override fun method(): String = "answerWebAppQuery"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<SentWebAppMessage>
|
||||||
|
get() = SentWebAppMessage.serializer()
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class ClearMyDefaultAdministratorRights(
|
||||||
|
@SerialName(forChannelsField)
|
||||||
|
val forChannels: Boolean? = null
|
||||||
|
) : SimpleRequest<Boolean> {
|
||||||
|
override fun method(): String = "setMyDefaultAdministratorRights"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
get() = Boolean.serializer()
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.ChatMember.AdministratorChatMemberImpl
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GetMyDefaultAdministratorRights(
|
||||||
|
@SerialName(forChannelsField)
|
||||||
|
val forChannels: Boolean? = null
|
||||||
|
) : SimpleRequest<AdministratorChatMemberImpl> {
|
||||||
|
override fun method(): String = "getMyDefaultAdministratorRights"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<AdministratorChatMemberImpl>
|
||||||
|
get() = AdministratorChatMemberImpl.serializer()
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ForChannels = GetMyDefaultAdministratorRights(true)
|
||||||
|
val ForGroups = GetMyDefaultAdministratorRights(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class SetMyDefaultAdministratorRights(
|
||||||
|
@SerialName(rightsField)
|
||||||
|
val rights: ChatAdministratorRightsImpl,
|
||||||
|
@SerialName(forChannelsField)
|
||||||
|
val forChannels: Boolean? = null
|
||||||
|
) : SimpleRequest<Boolean> {
|
||||||
|
override fun method(): String = "setMyDefaultAdministratorRights"
|
||||||
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
get() = Boolean.serializer()
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.chat.get
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GetChatMenuButton(
|
||||||
|
@SerialName(chatIdField)
|
||||||
|
override val chatId: ChatIdentifier
|
||||||
|
) : ChatRequest, SimpleRequest<MenuButton> {
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
override fun method(): String = GetDefaultChatMenuButton.method()
|
||||||
|
|
||||||
|
override val resultDeserializer: DeserializationStrategy<MenuButton>
|
||||||
|
get() = MenuButtonSerializer
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.chat.get
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.types.OptionalChatRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object GetDefaultChatMenuButton : OptionalChatRequest, SimpleRequest<MenuButton> {
|
||||||
|
override val chatId: ChatIdentifier?
|
||||||
|
get() = null
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
override fun method(): String = "getChatMenuButton"
|
||||||
|
|
||||||
|
override val resultDeserializer: DeserializationStrategy<MenuButton>
|
||||||
|
get() = MenuButtonSerializer
|
||||||
|
}
|
||||||
@@ -32,8 +32,8 @@ data class PromoteChatMember(
|
|||||||
private val canPinMessages: Boolean? = null,
|
private val canPinMessages: Boolean? = null,
|
||||||
@SerialName(canPromoteMembersField)
|
@SerialName(canPromoteMembersField)
|
||||||
private val canPromoteMembers: Boolean? = null,
|
private val canPromoteMembers: Boolean? = null,
|
||||||
@SerialName(canManageVoiceChatsField)
|
@SerialName(canManageVideoChatsField)
|
||||||
private val canManageVoiceChats: Boolean? = null,
|
private val canManageVideoChats: Boolean? = null,
|
||||||
@SerialName(canManageChatField)
|
@SerialName(canManageChatField)
|
||||||
private val canManageChat: Boolean? = null
|
private val canManageChat: Boolean? = null
|
||||||
) : ChatMemberRequest<Boolean>, UntilDate {
|
) : ChatMemberRequest<Boolean>, UntilDate {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.chat.modify
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SetChatMenuButton(
|
||||||
|
@SerialName(chatIdField)
|
||||||
|
override val chatId: ChatIdentifier,
|
||||||
|
@Serializable(MenuButtonSerializer::class)
|
||||||
|
@SerialName(menuButtonField)
|
||||||
|
val menuButton: MenuButton
|
||||||
|
) : ChatRequest, SimpleRequest<Boolean> {
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
override fun method(): String = SetDefaultChatMenuButton.method()
|
||||||
|
|
||||||
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
get() = Boolean.serializer()
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.chat.modify
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SetDefaultChatMenuButton(
|
||||||
|
@Serializable(MenuButtonSerializer::class)
|
||||||
|
@SerialName(menuButtonField)
|
||||||
|
val menuButton: MenuButton
|
||||||
|
) : SimpleRequest<Boolean> {
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
override fun method(): String = Companion.method()
|
||||||
|
|
||||||
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
get() = Boolean.serializer()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun method() = "setChatMenuButton"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,8 +8,8 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ fun AddAnimatedStickerToSet(
|
|||||||
return when (sticker) {
|
return when (sticker) {
|
||||||
is MultipartFile -> CommonMultipartFileRequest(
|
is MultipartFile -> CommonMultipartFileRequest(
|
||||||
data,
|
data,
|
||||||
mapOf(pngStickerField to sticker)
|
mapOf(tgsStickerField to sticker)
|
||||||
)
|
)
|
||||||
is FileId -> data
|
is FileId -> data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.stickers
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
|
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.StandardStickerSetAction
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
fun AddVideoStickerToSet(
|
||||||
|
userId: UserId,
|
||||||
|
stickerSetName: String,
|
||||||
|
sticker: InputFile,
|
||||||
|
emojis: String,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
): Request<Boolean> {
|
||||||
|
val data = AddVideoStickerToSet(userId, stickerSetName, emojis, sticker as? FileId, maskPosition)
|
||||||
|
return when (sticker) {
|
||||||
|
is MultipartFile -> CommonMultipartFileRequest(
|
||||||
|
data,
|
||||||
|
mapOf(webmStickerField to sticker)
|
||||||
|
)
|
||||||
|
is FileId -> data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class AddVideoStickerToSet internal constructor(
|
||||||
|
@SerialName(userIdField)
|
||||||
|
override val userId: UserId,
|
||||||
|
@SerialName(nameField)
|
||||||
|
override val name: String,
|
||||||
|
@SerialName(emojisField)
|
||||||
|
override val emojis: String,
|
||||||
|
@SerialName(webmStickerField)
|
||||||
|
val sticker: FileId? = null,
|
||||||
|
@SerialName(maskPositionField)
|
||||||
|
override val maskPosition: MaskPosition? = null
|
||||||
|
) : StandardStickerSetAction {
|
||||||
|
init {
|
||||||
|
if(emojis.isEmpty()) {
|
||||||
|
throw IllegalArgumentException("Emojis must not be empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
override fun method(): String = "addStickerToSet"
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.requests.stickers
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.CreateStickerSetAction
|
||||||
import dev.inmo.tgbotapi.requests.stickers.abstracts.StandardStickerSetAction
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.StandardStickerSetAction
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
@@ -10,16 +11,17 @@ import kotlinx.serialization.*
|
|||||||
fun CreateNewAnimatedStickerSet(
|
fun CreateNewAnimatedStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: InputFile,
|
sticker: InputFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
): Request<Boolean> {
|
): Request<Boolean> {
|
||||||
val data = CreateNewAnimatedStickerSet(userId, name, emojis, sticker as? FileId, containsMasks, maskPosition)
|
val data = CreateNewAnimatedStickerSet(userId, name, title, emojis, sticker as? FileId, containsMasks, maskPosition)
|
||||||
return when (sticker) {
|
return when (sticker) {
|
||||||
is MultipartFile -> CommonMultipartFileRequest(
|
is MultipartFile -> CommonMultipartFileRequest(
|
||||||
data,
|
data,
|
||||||
mapOf(pngStickerField to sticker)
|
mapOf(tgsStickerField to sticker)
|
||||||
)
|
)
|
||||||
is FileId -> data
|
is FileId -> data
|
||||||
}
|
}
|
||||||
@@ -31,6 +33,8 @@ data class CreateNewAnimatedStickerSet internal constructor(
|
|||||||
override val userId: UserId,
|
override val userId: UserId,
|
||||||
@SerialName(nameField)
|
@SerialName(nameField)
|
||||||
override val name: String,
|
override val name: String,
|
||||||
|
@SerialName(titleField)
|
||||||
|
override val title: String,
|
||||||
@SerialName(emojisField)
|
@SerialName(emojisField)
|
||||||
override val emojis: String,
|
override val emojis: String,
|
||||||
@SerialName(tgsStickerField)
|
@SerialName(tgsStickerField)
|
||||||
@@ -39,7 +43,7 @@ data class CreateNewAnimatedStickerSet internal constructor(
|
|||||||
val containsMasks: Boolean? = null,
|
val containsMasks: Boolean? = null,
|
||||||
@SerialName(maskPositionField)
|
@SerialName(maskPositionField)
|
||||||
override val maskPosition: MaskPosition? = null
|
override val maskPosition: MaskPosition? = null
|
||||||
) : StandardStickerSetAction {
|
) : CreateStickerSetAction {
|
||||||
init {
|
init {
|
||||||
if(emojis.isEmpty()) {
|
if(emojis.isEmpty()) {
|
||||||
throw IllegalArgumentException("Emojis must not be empty")
|
throw IllegalArgumentException("Emojis must not be empty")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.requests.stickers
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.CreateStickerSetAction
|
||||||
import dev.inmo.tgbotapi.requests.stickers.abstracts.StandardStickerSetAction
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.StandardStickerSetAction
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
@@ -10,12 +11,13 @@ import kotlinx.serialization.*
|
|||||||
fun CreateNewStaticStickerSet(
|
fun CreateNewStaticStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: InputFile,
|
sticker: InputFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
): Request<Boolean> {
|
): Request<Boolean> {
|
||||||
val data = CreateNewStaticStickerSet(userId, name, emojis, sticker as? FileId, containsMasks, maskPosition)
|
val data = CreateNewStaticStickerSet(userId, name, title, emojis, sticker as? FileId, containsMasks, maskPosition)
|
||||||
return when (sticker) {
|
return when (sticker) {
|
||||||
is MultipartFile -> CommonMultipartFileRequest(
|
is MultipartFile -> CommonMultipartFileRequest(
|
||||||
data,
|
data,
|
||||||
@@ -28,11 +30,12 @@ fun CreateNewStaticStickerSet(
|
|||||||
fun CreateNewStickerSet(
|
fun CreateNewStickerSet(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
name: String,
|
name: String,
|
||||||
|
title: String,
|
||||||
sticker: InputFile,
|
sticker: InputFile,
|
||||||
emojis: String,
|
emojis: String,
|
||||||
containsMasks: Boolean? = null,
|
containsMasks: Boolean? = null,
|
||||||
maskPosition: MaskPosition? = null
|
maskPosition: MaskPosition? = null
|
||||||
): Request<Boolean> = CreateNewStaticStickerSet(userId, name, sticker, emojis, containsMasks, maskPosition)
|
): Request<Boolean> = CreateNewStaticStickerSet(userId, name, title, sticker, emojis, containsMasks, maskPosition)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class CreateNewStaticStickerSet internal constructor(
|
data class CreateNewStaticStickerSet internal constructor(
|
||||||
@@ -40,6 +43,8 @@ data class CreateNewStaticStickerSet internal constructor(
|
|||||||
override val userId: UserId,
|
override val userId: UserId,
|
||||||
@SerialName(nameField)
|
@SerialName(nameField)
|
||||||
override val name: String,
|
override val name: String,
|
||||||
|
@SerialName(titleField)
|
||||||
|
override val title: String,
|
||||||
@SerialName(emojisField)
|
@SerialName(emojisField)
|
||||||
override val emojis: String,
|
override val emojis: String,
|
||||||
@SerialName(pngStickerField)
|
@SerialName(pngStickerField)
|
||||||
@@ -48,7 +53,7 @@ data class CreateNewStaticStickerSet internal constructor(
|
|||||||
val containsMasks: Boolean? = null,
|
val containsMasks: Boolean? = null,
|
||||||
@SerialName(maskPositionField)
|
@SerialName(maskPositionField)
|
||||||
override val maskPosition: MaskPosition? = null
|
override val maskPosition: MaskPosition? = null
|
||||||
) : StandardStickerSetAction {
|
) : CreateStickerSetAction {
|
||||||
init {
|
init {
|
||||||
if(emojis.isEmpty()) {
|
if(emojis.isEmpty()) {
|
||||||
throw IllegalArgumentException("Emojis must not be empty")
|
throw IllegalArgumentException("Emojis must not be empty")
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.stickers
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
|
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.CreateStickerSetAction
|
||||||
|
import dev.inmo.tgbotapi.requests.stickers.abstracts.StandardStickerSetAction
|
||||||
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.stickers.MaskPosition
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
fun CreateNewVideoStickerSet(
|
||||||
|
userId: UserId,
|
||||||
|
linkName: String,
|
||||||
|
title: String,
|
||||||
|
sticker: InputFile,
|
||||||
|
emojis: String,
|
||||||
|
containsMasks: Boolean? = null,
|
||||||
|
maskPosition: MaskPosition? = null
|
||||||
|
): Request<Boolean> {
|
||||||
|
val data = CreateNewVideoStickerSet(userId, linkName, title, emojis, sticker as? FileId, containsMasks, maskPosition)
|
||||||
|
return when (sticker) {
|
||||||
|
is MultipartFile -> CommonMultipartFileRequest(
|
||||||
|
data,
|
||||||
|
mapOf(webmStickerField to sticker)
|
||||||
|
)
|
||||||
|
is FileId -> data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CreateNewVideoStickerSet internal constructor(
|
||||||
|
@SerialName(userIdField)
|
||||||
|
override val userId: UserId,
|
||||||
|
@SerialName(nameField)
|
||||||
|
override val name: String,
|
||||||
|
@SerialName(titleField)
|
||||||
|
override val title: String,
|
||||||
|
@SerialName(emojisField)
|
||||||
|
override val emojis: String,
|
||||||
|
@SerialName(webmStickerField)
|
||||||
|
val sticker: FileId? = null,
|
||||||
|
@SerialName(containsMasksField)
|
||||||
|
val containsMasks: Boolean? = null,
|
||||||
|
@SerialName(maskPositionField)
|
||||||
|
override val maskPosition: MaskPosition? = null
|
||||||
|
) : CreateStickerSetAction {
|
||||||
|
init {
|
||||||
|
if(emojis.isEmpty()) {
|
||||||
|
throw IllegalArgumentException("Emojis must not be empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
get() = serializer()
|
||||||
|
|
||||||
|
override fun method(): String = "createNewStickerSet"
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests.stickers.abstracts
|
||||||
|
|
||||||
|
interface CreateStickerSetAction : StandardStickerSetAction {
|
||||||
|
val title: String
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package dev.inmo.tgbotapi.types
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatAdministratorRights
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ChatAdministratorRightsImpl(
|
||||||
|
@SerialName(canChangeInfoField)
|
||||||
|
override val canChangeInfo: Boolean = false,
|
||||||
|
@SerialName(canPostMessagesField)
|
||||||
|
override val canPostMessages: Boolean = false,
|
||||||
|
@SerialName(canEditMessagesField)
|
||||||
|
override val canEditMessages: Boolean = false,
|
||||||
|
@SerialName(canDeleteMessagesField)
|
||||||
|
override val canRemoveMessages: Boolean = false,
|
||||||
|
@SerialName(canInviteUsersField)
|
||||||
|
override val canInviteUsers: Boolean = false,
|
||||||
|
@SerialName(canRestrictMembersField)
|
||||||
|
override val canRestrictMembers: Boolean = false,
|
||||||
|
@SerialName(canPinMessagesField)
|
||||||
|
override val canPinMessages: Boolean = false,
|
||||||
|
@SerialName(canPromoteMembersField)
|
||||||
|
override val canPromoteMembers: Boolean = false,
|
||||||
|
@SerialName(canManageVideoChatsField)
|
||||||
|
override val canManageVideoChats: Boolean = false,
|
||||||
|
@SerialName(canManageChatField)
|
||||||
|
override val canManageChat: Boolean = false,
|
||||||
|
@SerialName(isAnonymousField)
|
||||||
|
override val isAnonymous: Boolean = false
|
||||||
|
) : ChatAdministratorRights
|
||||||
@@ -46,6 +46,9 @@ fun Byte.toChatId(): ChatId = toLong().toChatId()
|
|||||||
data class Username(
|
data class Username(
|
||||||
val username: String
|
val username: String
|
||||||
) : ChatIdentifier() {
|
) : ChatIdentifier() {
|
||||||
|
val usernameWithoutAt
|
||||||
|
get() = username.dropWhile { it == '@' }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (!username.startsWith("@")) {
|
if (!username.startsWith("@")) {
|
||||||
throw IllegalArgumentException("Username must starts with `@`")
|
throw IllegalArgumentException("Username must starts with `@`")
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ data class AdministratorChatMemberImpl(
|
|||||||
override val canPinMessages: Boolean = false,
|
override val canPinMessages: Boolean = false,
|
||||||
@SerialName(canPromoteMembersField)
|
@SerialName(canPromoteMembersField)
|
||||||
override val canPromoteMembers: Boolean = false,
|
override val canPromoteMembers: Boolean = false,
|
||||||
@SerialName(canManageVoiceChatsField)
|
@SerialName(canManageVideoChatsField)
|
||||||
override val canManageVoiceChats: Boolean = false,
|
override val canManageVideoChats: Boolean = false,
|
||||||
@SerialName(canManageChatField)
|
@SerialName(canManageChatField)
|
||||||
override val canManageChat: Boolean = false,
|
override val canManageChat: Boolean = false,
|
||||||
@SerialName(isAnonymousField)
|
@SerialName(isAnonymousField)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ data class CreatorChatMember(
|
|||||||
@Transient
|
@Transient
|
||||||
override val canPromoteMembers: Boolean = true
|
override val canPromoteMembers: Boolean = true
|
||||||
@Transient
|
@Transient
|
||||||
override val canManageVoiceChats: Boolean = true
|
override val canManageVideoChats: Boolean = true
|
||||||
@Transient
|
@Transient
|
||||||
override val canManageChat: Boolean = true
|
override val canManageChat: Boolean = true
|
||||||
@SerialName(statusField)
|
@SerialName(statusField)
|
||||||
|
|||||||
@@ -8,17 +8,12 @@ import kotlinx.serialization.encoding.Decoder
|
|||||||
import kotlinx.serialization.encoding.Encoder
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
@Serializable(AdministratorChatMemberSerializer::class)
|
@Serializable(AdministratorChatMemberSerializer::class)
|
||||||
interface AdministratorChatMember : SpecialRightsChatMember {
|
interface AdministratorChatMember : SpecialRightsChatMember, ChatAdministratorRights {
|
||||||
val canBeEdited: Boolean
|
val canBeEdited: Boolean
|
||||||
val canPostMessages: Boolean
|
|
||||||
val canEditMessages: Boolean
|
|
||||||
val canRemoveMessages: Boolean
|
|
||||||
val canRestrictMembers: Boolean
|
|
||||||
val canPromoteMembers: Boolean
|
|
||||||
val canManageVoiceChats: Boolean
|
|
||||||
val canManageChat: Boolean
|
|
||||||
val isAnonymous: Boolean
|
|
||||||
val customTitle: String?
|
val customTitle: String?
|
||||||
|
|
||||||
|
val canManageVoiceChats: Boolean
|
||||||
|
get() = canManageVideoChats
|
||||||
}
|
}
|
||||||
|
|
||||||
@RiskFeature
|
@RiskFeature
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.ChatMember.abstracts
|
||||||
|
|
||||||
|
sealed interface SpecialChatAdministratorRights {
|
||||||
|
val canChangeInfo: Boolean
|
||||||
|
val canInviteUsers: Boolean
|
||||||
|
val canPinMessages: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChatAdministratorRights : SpecialChatAdministratorRights {
|
||||||
|
val isAnonymous: Boolean
|
||||||
|
val canManageChat: Boolean
|
||||||
|
val canRemoveMessages: Boolean
|
||||||
|
val canManageVideoChats: Boolean
|
||||||
|
val canRestrictMembers: Boolean
|
||||||
|
val canPromoteMembers: Boolean
|
||||||
|
val canPostMessages: Boolean
|
||||||
|
val canEditMessages: Boolean
|
||||||
|
}
|
||||||
@@ -3,8 +3,4 @@ package dev.inmo.tgbotapi.types.ChatMember.abstracts
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(ChatMemberSerializer::class)
|
@Serializable(ChatMemberSerializer::class)
|
||||||
interface SpecialRightsChatMember : ChatMember {
|
interface SpecialRightsChatMember : ChatMember, SpecialChatAdministratorRights
|
||||||
val canChangeInfo: Boolean
|
|
||||||
val canInviteUsers: Boolean
|
|
||||||
val canPinMessages: Boolean
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ typealias FoursquareType = String
|
|||||||
typealias GooglePlaceId = String
|
typealias GooglePlaceId = String
|
||||||
typealias GooglePlaceType = String
|
typealias GooglePlaceType = String
|
||||||
typealias MembersLimit = Int
|
typealias MembersLimit = Int
|
||||||
|
typealias WebAppQueryId = String
|
||||||
|
|
||||||
typealias Seconds = Int
|
typealias Seconds = Int
|
||||||
typealias MilliSeconds = Long
|
typealias MilliSeconds = Long
|
||||||
@@ -133,6 +134,7 @@ const val inlineMessageIdField = "inline_message_id"
|
|||||||
const val callbackDataField = "callback_data"
|
const val callbackDataField = "callback_data"
|
||||||
const val callbackGameField = "callback_game"
|
const val callbackGameField = "callback_game"
|
||||||
const val callbackQueryIdField = "callback_query_id"
|
const val callbackQueryIdField = "callback_query_id"
|
||||||
|
const val webAppQueryIdField = "web_app_query_id"
|
||||||
const val inlineQueryIdField = "inline_query_id"
|
const val inlineQueryIdField = "inline_query_id"
|
||||||
const val inlineKeyboardField = "inline_keyboard"
|
const val inlineKeyboardField = "inline_keyboard"
|
||||||
const val showAlertField = "show_alert"
|
const val showAlertField = "show_alert"
|
||||||
@@ -154,6 +156,7 @@ const val dropPendingUpdatesField = "drop_pending_updates"
|
|||||||
const val hasCustomCertificateField = "has_custom_certificate"
|
const val hasCustomCertificateField = "has_custom_certificate"
|
||||||
const val pendingUpdateCountField = "pending_update_count"
|
const val pendingUpdateCountField = "pending_update_count"
|
||||||
const val lastErrorDateField = "last_error_date"
|
const val lastErrorDateField = "last_error_date"
|
||||||
|
const val lastSynchronizationErrorDateField = "last_synchronization_error_date"
|
||||||
const val lastErrorMessageField = "last_error_message"
|
const val lastErrorMessageField = "last_error_message"
|
||||||
const val votesCountField = "voter_count"
|
const val votesCountField = "voter_count"
|
||||||
const val isClosedField = "is_closed"
|
const val isClosedField = "is_closed"
|
||||||
@@ -168,6 +171,7 @@ const val botUsernameField = "bot_username"
|
|||||||
const val switchInlineQueryCurrentChatField = "switch_inline_query_current_chat"
|
const val switchInlineQueryCurrentChatField = "switch_inline_query_current_chat"
|
||||||
const val switchInlineQueryField = "switch_inline_query"
|
const val switchInlineQueryField = "switch_inline_query"
|
||||||
const val isAnimatedField = "is_animated"
|
const val isAnimatedField = "is_animated"
|
||||||
|
const val isVideoField = "is_video"
|
||||||
const val inviteLinkField = "invite_link"
|
const val inviteLinkField = "invite_link"
|
||||||
const val pinnedMessageField = "pinned_message"
|
const val pinnedMessageField = "pinned_message"
|
||||||
const val customTitleField = "custom_title"
|
const val customTitleField = "custom_title"
|
||||||
@@ -262,9 +266,13 @@ const val canRestrictMembersField = "can_restrict_members"
|
|||||||
const val canPinMessagesField = "can_pin_messages"
|
const val canPinMessagesField = "can_pin_messages"
|
||||||
const val canPromoteMembersField = "can_promote_members"
|
const val canPromoteMembersField = "can_promote_members"
|
||||||
const val canManageVoiceChatsField = "can_manage_voice_chats"
|
const val canManageVoiceChatsField = "can_manage_voice_chats"
|
||||||
|
const val canManageVideoChatsField = "can_manage_video_chats"
|
||||||
|
const val rightsField = "rights"
|
||||||
|
const val forChannelsField = "for_channels"
|
||||||
const val canManageChatField = "can_manage_chat"
|
const val canManageChatField = "can_manage_chat"
|
||||||
const val pngStickerField = "png_sticker"
|
const val pngStickerField = "png_sticker"
|
||||||
const val tgsStickerField = "tgs_sticker"
|
const val tgsStickerField = "tgs_sticker"
|
||||||
|
const val webmStickerField = "webm_sticker"
|
||||||
const val oldChatMemberField = "old_chat_member"
|
const val oldChatMemberField = "old_chat_member"
|
||||||
const val newChatMemberField = "new_chat_member"
|
const val newChatMemberField = "new_chat_member"
|
||||||
|
|
||||||
@@ -311,6 +319,7 @@ const val pricesField = "prices"
|
|||||||
const val payloadField = "payload"
|
const val payloadField = "payload"
|
||||||
const val vcardField = "vcard"
|
const val vcardField = "vcard"
|
||||||
const val resultsField = "results"
|
const val resultsField = "results"
|
||||||
|
const val resultField = "result"
|
||||||
const val certificateField = "certificate"
|
const val certificateField = "certificate"
|
||||||
const val questionField = "question"
|
const val questionField = "question"
|
||||||
const val optionsField = "options"
|
const val optionsField = "options"
|
||||||
@@ -428,3 +437,7 @@ const val bankStatementField = "bank_statement"
|
|||||||
const val rentalAgreementField = "rental_agreement"
|
const val rentalAgreementField = "rental_agreement"
|
||||||
const val passportRegistrationField = "passport_registration"
|
const val passportRegistrationField = "passport_registration"
|
||||||
const val temporaryRegistrationField = "temporary_registration"
|
const val temporaryRegistrationField = "temporary_registration"
|
||||||
|
|
||||||
|
const val buttonTextField = "button_text"
|
||||||
|
const val webAppField = "web_app"
|
||||||
|
const val menuButtonField = "menu_button"
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package dev.inmo.tgbotapi.types
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
@Serializable(MenuButtonSerializer::class)
|
||||||
|
sealed interface MenuButton {
|
||||||
|
@Required
|
||||||
|
val type: String
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object Commands : MenuButton {
|
||||||
|
@Required
|
||||||
|
override val type: String
|
||||||
|
get() = "commands"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class WebApp(
|
||||||
|
val text: String,
|
||||||
|
@SerialName(webAppField)
|
||||||
|
val webApp: WebAppInfo
|
||||||
|
) : MenuButton {
|
||||||
|
@Required
|
||||||
|
override val type: String
|
||||||
|
get() = Companion.type
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val type: String
|
||||||
|
get() = "web_app"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object Default : MenuButton {
|
||||||
|
@Required
|
||||||
|
override val type: String
|
||||||
|
get() = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@RiskFeature
|
||||||
|
data class Unknown (
|
||||||
|
override val type: String,
|
||||||
|
val rawJson: JsonElement
|
||||||
|
) : MenuButton
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun serializer(): KSerializer<MenuButton> = MenuButtonSerializer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
internal data class MenuButtonSurrogate(
|
||||||
|
val type: String,
|
||||||
|
val text: String? = null,
|
||||||
|
@SerialName(webAppField)
|
||||||
|
val webApp: WebAppInfo? = null,
|
||||||
|
val srcJsonElement: JsonElement? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializer(MenuButton::class)
|
||||||
|
object MenuButtonSerializer : KSerializer<MenuButton> {
|
||||||
|
override val descriptor: SerialDescriptor
|
||||||
|
get() = MenuButtonSurrogate.serializer().descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): MenuButton {
|
||||||
|
val surrogate = if (decoder is JsonDecoder) {
|
||||||
|
val json = JsonElement.serializer().deserialize(decoder)
|
||||||
|
runCatching {
|
||||||
|
decoder.json.decodeFromJsonElement(MenuButtonSurrogate.serializer(), json)
|
||||||
|
}.onFailure {
|
||||||
|
return MenuButton.Unknown(
|
||||||
|
runCatching { json.jsonObject[typeField] ?.jsonPrimitive ?.content }.getOrNull() ?: "",
|
||||||
|
json
|
||||||
|
)
|
||||||
|
}.getOrThrow().copy(
|
||||||
|
srcJsonElement = json
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
MenuButtonSurrogate.serializer().deserialize(decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (surrogate.type) {
|
||||||
|
MenuButton.Commands.type -> MenuButton.Commands
|
||||||
|
MenuButton.Default.type -> MenuButton.Default
|
||||||
|
MenuButton.WebApp.type -> if (surrogate.text != null && surrogate.webApp != null) {
|
||||||
|
MenuButton.WebApp(surrogate.text, surrogate.webApp)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
} ?: MenuButton.Unknown(
|
||||||
|
surrogate.type,
|
||||||
|
surrogate.srcJsonElement ?: buildJsonObject { }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: MenuButton) {
|
||||||
|
encoder.encodeSerializableValue(
|
||||||
|
MenuButtonSurrogate.serializer(),
|
||||||
|
when (value) {
|
||||||
|
MenuButton.Default,
|
||||||
|
MenuButton.Commands -> MenuButtonSurrogate(value.type)
|
||||||
|
is MenuButton.WebApp -> MenuButtonSurrogate(value.type, value.text, value.webApp)
|
||||||
|
is MenuButton.Unknown -> {
|
||||||
|
encoder.encodeSerializableValue(
|
||||||
|
JsonElement.serializer(),
|
||||||
|
value.rawJson
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,11 +20,11 @@ internal data class RawMessageEntity(
|
|||||||
|
|
||||||
internal fun RawMessageEntity.asTextSource(
|
internal fun RawMessageEntity.asTextSource(
|
||||||
source: String,
|
source: String,
|
||||||
subParts: TextSourcesList
|
subParts: List<Pair<Int, TextSource>>
|
||||||
): TextSource {
|
): TextSource {
|
||||||
val sourceSubstring: String = source.substring(range)
|
val sourceSubstring: String = source.substring(range)
|
||||||
val subPartsWithRegulars by lazy {
|
val subPartsWithRegulars by lazy {
|
||||||
subParts.fillWithRegulars(sourceSubstring)
|
subParts.map { (it.first - offset) to it.second }.fillWithRegulars(sourceSubstring)
|
||||||
}
|
}
|
||||||
return when (type) {
|
return when (type) {
|
||||||
"mention" -> MentionTextSource(sourceSubstring, subPartsWithRegulars)
|
"mention" -> MentionTextSource(sourceSubstring, subPartsWithRegulars)
|
||||||
@@ -58,16 +58,14 @@ private inline operator fun <T : Comparable<T>> ClosedRange<T>.contains(other: C
|
|||||||
return start <= other.start && endInclusive >= other.endInclusive
|
return start <= other.start && endInclusive >= other.endInclusive
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun TextSourcesList.fillWithRegulars(source: String): TextSourcesList {
|
internal fun List<Pair<Int, TextSource>>.fillWithRegulars(source: String): TextSourcesList {
|
||||||
var index = 0
|
var index = 0
|
||||||
val result = mutableListOf<TextSource>()
|
val result = mutableListOf<TextSource>()
|
||||||
for (i in 0 until size) {
|
for (i in indices) {
|
||||||
val textSource = get(i)
|
val (offset, textSource) = get(i)
|
||||||
val thisSourceInStart = source.startsWith(textSource.source, index)
|
if (offset - index > 0) {
|
||||||
if (!thisSourceInStart) {
|
result.add(regular(source.substring(index, offset)))
|
||||||
val regularEndIndex = source.indexOf(textSource.source, index)
|
index = offset
|
||||||
result.add(regular(source.substring(index, regularEndIndex)))
|
|
||||||
index = regularEndIndex
|
|
||||||
}
|
}
|
||||||
result.add(textSource)
|
result.add(textSource)
|
||||||
index += textSource.source.length
|
index += textSource.source.length
|
||||||
@@ -83,9 +81,9 @@ internal fun TextSourcesList.fillWithRegulars(source: String): TextSourcesList {
|
|||||||
private fun createTextSources(
|
private fun createTextSources(
|
||||||
originalFullString: String,
|
originalFullString: String,
|
||||||
entities: RawMessageEntities
|
entities: RawMessageEntities
|
||||||
): TextSourcesList {
|
): List<Pair<Int, TextSource>> {
|
||||||
val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } }
|
val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } }
|
||||||
val resultList = mutableListOf<TextSource>()
|
val resultList = mutableListOf<Pair<Int, TextSource>>()
|
||||||
|
|
||||||
while (mutableEntities.isNotEmpty()) {
|
while (mutableEntities.isNotEmpty()) {
|
||||||
var parent = mutableEntities.removeFirst()
|
var parent = mutableEntities.removeFirst()
|
||||||
@@ -129,7 +127,7 @@ private fun createTextSources(
|
|||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
resultList.add(
|
resultList.add(
|
||||||
parent.asTextSource(
|
parent.offset to parent.asTextSource(
|
||||||
originalFullString,
|
originalFullString,
|
||||||
subtextSources
|
subtextSources
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.Username
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||||
import dev.inmo.tgbotapi.utils.internal.*
|
import dev.inmo.tgbotapi.utils.internal.*
|
||||||
@@ -23,6 +24,7 @@ data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructo
|
|||||||
override val markdown: String by lazy { source.mentionMarkdown() }
|
override val markdown: String by lazy { source.mentionMarkdown() }
|
||||||
override val markdownV2: String by lazy { mentionMarkdownV2() }
|
override val markdownV2: String by lazy { mentionMarkdownV2() }
|
||||||
override val html: String by lazy { mentionHTML() }
|
override val html: String by lazy { mentionHTML() }
|
||||||
|
val username: Username = Username(source)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (!source.startsWith("@")) {
|
if (!source.startsWith("@")) {
|
||||||
@@ -42,3 +44,6 @@ inline fun mention(vararg parts: TextSource) = mention(parts.toList())
|
|||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun mention(whoToMention: String) = mention(regular(whoToMention))
|
inline fun mention(whoToMention: String) = mention(regular(whoToMention))
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun mention(whoToMention: Username) = mention(whoToMention.username.dropWhile { it == '@' })
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,12 @@ inline fun mention(parts: TextSourcesList, id: Identifier) = mention(parts, User
|
|||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun Identifier.mention(parts: TextSourcesList) = mention(parts, this)
|
inline fun Identifier.mention(parts: TextSourcesList) = mention(parts, this)
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun mention(user: User, vararg parts: TextSource) = mention(parts.toList(), user)
|
inline fun mention(user: User, vararg parts: TextSource) = mention(
|
||||||
|
textSourcesOrElseTextSource(parts.toList()) {
|
||||||
|
RegularTextSource("${user.lastName} ${user.firstName}")
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun mention(text: String, user: User) = mention(user, regular(text))
|
inline fun mention(text: String, user: User) = mention(user, regular(text))
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
|
import kotlin.js.JsName
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
|
@RiskFeature
|
||||||
|
inline fun textSourcesOrElse(
|
||||||
|
textSources: TextSourcesList,
|
||||||
|
block: () -> TextSourcesList
|
||||||
|
): TextSourcesList = textSources.takeIf { it.isNotEmpty() } ?: block()
|
||||||
|
|
||||||
|
@RiskFeature
|
||||||
|
inline fun textSourcesOrElseTextSource(
|
||||||
|
textSources: TextSourcesList,
|
||||||
|
block: () -> TextSource
|
||||||
|
): TextSourcesList = textSources.takeIf { it.isNotEmpty() } ?: listOf(block())
|
||||||
@@ -16,6 +16,8 @@ data class WebhookInfo(
|
|||||||
val allowedUpdates: List<String> = ALL_UPDATES_LIST,
|
val allowedUpdates: List<String> = ALL_UPDATES_LIST,
|
||||||
@SerialName(lastErrorDateField)
|
@SerialName(lastErrorDateField)
|
||||||
val lastErrorDate: TelegramDate? = null,
|
val lastErrorDate: TelegramDate? = null,
|
||||||
|
@SerialName(lastSynchronizationErrorDateField)
|
||||||
|
val lastSynchronizationErrorDate: TelegramDate? = null,
|
||||||
@SerialName(lastErrorMessageField)
|
@SerialName(lastErrorMessageField)
|
||||||
val lastErrorMessage: String? = null
|
val lastErrorMessage: String? = null
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.games.CallbackGame
|
import dev.inmo.tgbotapi.types.games.CallbackGame
|
||||||
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some button of [dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup]. See inheritors and visit
|
* Some button of [dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup]. See inheritors and visit
|
||||||
@@ -15,10 +16,14 @@ sealed interface InlineKeyboardButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class UnknownInlineKeyboardButton internal constructor(
|
data class UnknownInlineKeyboardButton (
|
||||||
override val text: String,
|
|
||||||
val rawData: JsonElement
|
val rawData: JsonElement
|
||||||
) : InlineKeyboardButton
|
) : InlineKeyboardButton {
|
||||||
|
override val text: String
|
||||||
|
get() = runCatching {
|
||||||
|
rawData.jsonObject[textField] ?.jsonPrimitive ?.content
|
||||||
|
}.getOrNull() ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This type of button must always be the first button in the first row. Visit
|
* This type of button must always be the first button in the first row. Visit
|
||||||
@@ -116,3 +121,14 @@ data class URLInlineKeyboardButton(
|
|||||||
@SerialName(urlField)
|
@SerialName(urlField)
|
||||||
val url: String
|
val url: String
|
||||||
) : InlineKeyboardButton
|
) : InlineKeyboardButton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button with [WebAppInfo]. Web App will be launched when the button is pressed. The Web App will be able to send a
|
||||||
|
* `web_app_data` service message. **Available in private chats only**.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class WebAppInlineKeyboardButton(
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(webAppField)
|
||||||
|
val webApp: WebAppInfo
|
||||||
|
) : InlineKeyboardButton
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
|
|||||||
|
|
||||||
return (json as? JsonObject) ?.let { resolveSerializer(it) } ?.let {
|
return (json as? JsonObject) ?.let { resolveSerializer(it) } ?.let {
|
||||||
nonstrictJsonFormat.decodeFromJsonElement(it, json)
|
nonstrictJsonFormat.decodeFromJsonElement(it, json)
|
||||||
} ?: UnknownInlineKeyboardButton("", json)
|
} ?: UnknownInlineKeyboardButton(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, value: InlineKeyboardButton) {
|
override fun serialize(encoder: Encoder, value: InlineKeyboardButton) {
|
||||||
@@ -48,6 +48,7 @@ object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> {
|
|||||||
is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value)
|
is SwitchInlineQueryInlineKeyboardButton -> SwitchInlineQueryInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value)
|
is SwitchInlineQueryCurrentChatInlineKeyboardButton -> SwitchInlineQueryCurrentChatInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is URLInlineKeyboardButton -> URLInlineKeyboardButton.serializer().serialize(encoder, value)
|
is URLInlineKeyboardButton -> URLInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
|
is WebAppInlineKeyboardButton -> WebAppInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value)
|
is CallbackGameInlineKeyboardButton -> CallbackGameInlineKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is UnknownInlineKeyboardButton -> JsonElement.serializer().serialize(encoder, value.rawData)
|
is UnknownInlineKeyboardButton -> JsonElement.serializer().serialize(encoder, value.rawData)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types.buttons
|
package dev.inmo.tgbotapi.types.buttons
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
@@ -63,10 +64,22 @@ data class RequestLocationKeyboardButton(
|
|||||||
override val text: String
|
override val text: String
|
||||||
) : KeyboardButton {
|
) : KeyboardButton {
|
||||||
@SerialName(requestLocationField)
|
@SerialName(requestLocationField)
|
||||||
@EncodeDefault
|
@Required
|
||||||
val requestLocation: Boolean = true
|
val requestLocation: Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private chats only. Description of the Web App that will be launched when the user presses the button. The Web App
|
||||||
|
* will be able to send an arbitrary message on behalf of the user using the method `answerWebAppQuery`. Available only
|
||||||
|
* in private chats between a user and the bot.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class WebAppKeyboardButton(
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(webAppField)
|
||||||
|
val webApp: WebAppInfo
|
||||||
|
) : KeyboardButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private chats only. When user will tap on this button, he will be asked for the poll with [requestPoll] options. You will be able
|
* Private chats only. When user will tap on this button, he will be asked for the poll with [requestPoll] options. You will be able
|
||||||
* to catch this poll in updates and data using [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPoll] in
|
* to catch this poll in updates and data using [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPoll] in
|
||||||
@@ -97,6 +110,13 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
|||||||
asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton(
|
asJson is JsonObject && asJson[requestLocationField] != null -> RequestLocationKeyboardButton(
|
||||||
asJson[textField]!!.jsonPrimitive.content
|
asJson[textField]!!.jsonPrimitive.content
|
||||||
)
|
)
|
||||||
|
asJson is JsonObject && asJson[webAppField] != null -> WebAppKeyboardButton(
|
||||||
|
asJson[textField]!!.jsonPrimitive.content,
|
||||||
|
nonstrictJsonFormat.decodeFromJsonElement(
|
||||||
|
WebAppInfo.serializer(),
|
||||||
|
asJson[webAppField]!!
|
||||||
|
)
|
||||||
|
)
|
||||||
asJson is JsonObject && asJson[requestPollField] != null -> RequestPollKeyboardButton(
|
asJson is JsonObject && asJson[requestPollField] != null -> RequestPollKeyboardButton(
|
||||||
asJson[textField]!!.jsonPrimitive.content,
|
asJson[textField]!!.jsonPrimitive.content,
|
||||||
nonstrictJsonFormat.decodeFromJsonElement(
|
nonstrictJsonFormat.decodeFromJsonElement(
|
||||||
@@ -119,6 +139,7 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
|||||||
when (value) {
|
when (value) {
|
||||||
is RequestContactKeyboardButton -> RequestContactKeyboardButton.serializer().serialize(encoder, value)
|
is RequestContactKeyboardButton -> RequestContactKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.serializer().serialize(encoder, value)
|
is RequestLocationKeyboardButton -> RequestLocationKeyboardButton.serializer().serialize(encoder, value)
|
||||||
|
is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
|
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is SimpleKeyboardButton -> encoder.encodeString(value.text)
|
is SimpleKeyboardButton -> encoder.encodeString(value.text)
|
||||||
is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw))
|
is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw))
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user