1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-17 20:40:20 +00:00

Compare commits

...

141 Commits

Author SHA1 Message Date
a6d9fa6ce3 update uuid 2023-12-10 13:43:43 +06:00
7fd2442f8b add inmonexus user/password 2023-12-10 13:39:59 +06:00
8b37ecea9e remove publishing to gitea 2023-12-10 13:39:10 +06:00
35fc9f60df replace gitea packages with nexus 2023-12-10 13:37:35 +06:00
68e89dc1ad Update build.gradle 2023-12-10 02:18:25 +06:00
129fb31b74 update dependencies 2023-12-08 16:13:02 +06:00
a2c353ca41 start 9.4.2 2023-12-08 16:10:48 +06:00
cb74abfce5 Merge pull request #806 from InsanusMokrassar/9.4.1
9.4.1
2023-11-26 13:43:38 +06:00
ca7314923e replace warning about two bots from LongPolling to DefaultKtorRequestsExecutor 2023-11-26 13:37:49 +06:00
74f625a53a start 9.4.1 2023-11-26 13:32:56 +06:00
3a5fed3dd9 Merge pull request #803 from InsanusMokrassar/9.4.0
9.4.0
2023-11-26 04:30:56 +06:00
6158143220 Update greetings.yml 2023-11-26 04:30:18 +06:00
f8182ddb85 Revert "pinned message in ExtendedOtherPartiesChat"
This reverts commit b7c3f9f607.
2023-11-26 03:20:05 +06:00
b7c3f9f607 pinned message in ExtendedOtherPartiesChat 2023-11-26 02:06:30 +06:00
8763ea23fa cratch fix of build fails 2023-11-25 17:54:40 +06:00
b412e7b3b7 improvement of DefaultKTgBotAPIKSLog 2023-11-25 12:56:00 +06:00
98e5d182bb update dependencies 2023-11-25 00:28:51 +06:00
ffc0f5abb7 add improvements in logging functionality 2023-11-23 20:00:52 +06:00
816cf00dac basically add logging 2023-11-23 12:47:58 +06:00
e34bc7453e update dependencies 2023-11-23 12:06:46 +06:00
3b2ccbf33b start 9.4.0 2023-11-23 12:00:32 +06:00
6ecfbdf56d improvements in publish.gradle 2023-11-05 13:22:32 +06:00
b49e1c50f5 remove temporal publish.gradle file 2023-11-05 13:09:54 +06:00
d7389dfcfe potential fix of publish.gradle 2023-11-05 13:09:29 +06:00
cf5cee3e53 Merge pull request #798 from InsanusMokrassar/9.3.0
9.3.0
2023-11-05 12:46:40 +06:00
8593263506 fill changelog 2023-11-05 12:36:36 +06:00
4422a4d09b update workflows jdk 2023-11-05 00:48:09 +06:00
9ecb50e377 update dependencies and gradle wrapper 2023-11-04 21:13:14 +06:00
8a4b40c6ec Update libs.versions.toml 2023-11-01 12:45:24 +06:00
bba667db30 Merge branch 'master' into 9.3.0 2023-10-31 18:45:52 +06:00
ca0d256bbb update dependencies 2023-10-31 18:43:51 +06:00
dc2fd07632 Merge pull request #797 from InsanusMokrassar/9.2.4
9.2.4
2023-10-25 19:59:05 +06:00
32fe008eef update docs remote url 2023-10-25 14:58:05 +06:00
2b938903b6 update kdocs 2023-10-25 14:55:46 +06:00
080db09d2c improvements of commands expectations and triggers 2023-10-25 14:36:32 +06:00
0efa52fe00 start 9.2.4 2023-10-25 13:34:41 +06:00
c4214798e3 Merge branch 'master' into 9.3.0-RC 2023-10-24 16:15:49 +06:00
fdf510153d Merge pull request #796 from InsanusMokrassar/9.2.3
9.2.3
2023-10-24 16:12:17 +06:00
edb16d7107 update gradle wrapper 2023-10-24 15:55:37 +06:00
c49f400201 fix in VoiceContent#createResend 2023-10-24 15:52:06 +06:00
db7de6edf8 start 9.2.3 2023-10-24 15:51:08 +06:00
a0b14233e0 update microutils 2023-10-20 22:35:03 +06:00
1a479706e2 update version of microutils and add arm platform target 2023-10-20 22:07:14 +06:00
2719e166a8 update workgflows 2023-10-17 23:46:28 +06:00
051684db23 update changelog 2023-10-17 23:43:13 +06:00
805cec76ce update kdokka 2023-10-17 23:39:30 +06:00
899c195fd5 update gradle wrapper 2023-10-17 23:38:31 +06:00
f5937fc4d6 upgrade up to 9.3.0-RC 2023-10-17 23:37:51 +06:00
8cf7b349df Merge branch 'master' into 9.3.0 2023-10-15 18:04:44 +06:00
bf8f8b9e6f update microutils 2023-10-15 17:49:13 +06:00
edc0b1c492 update ksp and ktor 2023-10-12 13:27:54 +06:00
a85d58aac1 update up to 1.9.20-RC🎉 2023-10-12 13:21:06 +06:00
10860e1bb2 Merge pull request #794 from InsanusMokrassar/9.2.2
9.2.2
2023-10-11 13:55:41 +06:00
46e6eeca9d improve serializers 2023-10-11 13:38:09 +06:00
80be86454d fix of #793 2023-10-11 13:07:07 +06:00
d5f5a0e30b start 9.2.2 2023-10-11 12:10:36 +06:00
826c27874d update microutils 2023-10-09 20:52:33 +06:00
4e917e8cf8 update libs and changelog with thanks to Anton Lakotka 2023-10-09 13:07:56 +06:00
051210caf5 Merge pull request #791 from InsanusMokrassar/9.2.1
9.2.1
2023-09-29 22:39:04 +06:00
284fe58848 upfix of chatmember statuses serialization 2023-09-29 22:38:22 +06:00
38c9732da5 update ktor version 2023-09-29 22:17:42 +06:00
dee13c03ae fix serialization/deserialization of chat member statuses 2023-09-29 22:16:10 +06:00
6103b70a47 start 9.2.1 2023-09-29 22:15:38 +06:00
96ffae2062 Update libs.versions.toml 2023-09-27 23:26:57 +06:00
4180721aed update dependencies 2023-09-27 18:18:30 +06:00
4ab0845333 migrate onto 9.3.0 2023-09-27 18:02:14 +06:00
3f9a4e95a3 update up to kotlin 1.9.20-Beta2 2023-09-27 18:02:14 +06:00
834d60ff16 update dependencies 2023-09-27 18:02:14 +06:00
650d96974f update dependencies 2023-09-27 18:02:14 +06:00
7f5cd0567b Merge pull request #789 from InsanusMokrassar/9.2.0
9.2.0
2023-09-25 23:27:06 +06:00
af159b89b6 update changelog and readme 2023-09-25 23:26:05 +06:00
efe286c181 improvements and fixes in web apps api 2023-09-25 23:21:48 +06:00
821bb5b45c improve cloud storage 2023-09-25 20:23:37 +06:00
c92ed92f7c add opportunity to create Hex from rgb 2023-09-25 16:26:27 +06:00
88f6b349ea fixes in onEvent/onWriteAccessRequested/onContactRequested 2023-09-25 14:14:04 +06:00
6c4afac8f8 small refactor of chat member 2023-09-24 21:50:32 +06:00
6273990b00 fix in chat member deserializing 2023-09-24 21:33:26 +06:00
1a1fd926dd temporarily change request id main type to ushort 2023-09-24 21:12:48 +06:00
affa2a3a57 ChatAdministratorRightsImpl -> ChatCommonAdministratorRights 2023-09-24 20:11:58 +06:00
73a748d8b3 ChatAdministratorRights -> ChatAdministratorRightsImpl in reply keyboards 2023-09-24 20:08:46 +06:00
fa4d264df4 add preview callbacks support 2023-09-23 00:40:32 +06:00
1b1da33882 add CloudStorage support 2023-09-23 00:15:58 +06:00
ccfb774f33 update promoteChatMember 2023-09-22 23:33:56 +06:00
5215e8a315 add support of stories rights 2023-09-22 22:53:14 +06:00
97a3901cb9 improvements of WriteAccessAllowed 2023-09-22 21:55:22 +06:00
034e87a8ef add support of several new things in bot api 2023-09-22 21:45:28 +06:00
156fbd72d4 start 9.2.0 2023-09-22 21:10:21 +06:00
8ec3e01737 Update build.gradle 2023-09-02 09:36:11 +06:00
1655bedabe Merge pull request #788 from InsanusMokrassar/9.1.2
9.1.2
2023-09-01 03:52:37 +06:00
ac6b580a7e fixes in message content serialization 2023-09-01 02:42:39 +06:00
c6692c2509 start 9.1.2 2023-09-01 02:20:53 +06:00
12846a68b9 Merge pull request #785 from InsanusMokrassar/9.1.1
9.1.1
2023-08-31 20:39:30 +06:00
21f5808b12 small refactoring 2023-08-31 19:35:01 +06:00
64244a60fe potential fix of incorrect parsing in 'RawMessageEntity' 2023-08-31 19:20:42 +06:00
4cd7fdb436 start 9.1.1 2023-08-31 19:03:36 +06:00
6daf98d47d Merge pull request #783 from InsanusMokrassar/9.1.0
9.1.0
2023-08-20 02:35:25 +06:00
c260597799 fixes in poll answer 2023-08-20 02:30:36 +06:00
d59e204002 rename PollAnswer inheritors 2023-08-20 00:27:33 +06:00
117d891ff2 update changelog and PollAnswer 2023-08-19 23:55:59 +06:00
1e451af508 update telegram bot api support info 2023-08-19 18:40:12 +06:00
051f5e22e7 fix of createResend in story content 2023-08-19 18:15:54 +06:00
6873c23309 complete story support 2023-08-19 16:41:08 +06:00
a65971be00 start add stories 2023-08-19 00:31:36 +06:00
4b5baaff8c add suport of unpinAllGeneralForumTopicMessages 2023-08-18 23:34:44 +06:00
0840d2e083 add emoji_status_expiration_date support in Chat 2023-08-18 23:31:30 +06:00
085a225eb4 add support of voter_chat in PollAnswer 2023-08-18 23:27:15 +06:00
b575871a8e update dependencies 2023-08-18 23:13:56 +06:00
c96e162845 start 9.1.0 2023-08-18 23:05:43 +06:00
c471d59b3c Merge pull request #774 from InsanusMokrassar/9.0.0
9.0.0
2023-07-01 14:37:43 +06:00
187f340e88 fixes in webappuser 2023-07-01 14:32:58 +06:00
77ea1f741e fill changelog 2023-07-01 14:30:37 +06:00
bff2713bbd one more fix of triggers 2023-07-01 14:26:46 +06:00
cf666aad11 update gradle wrapper 2023-07-01 14:24:35 +06:00
93e72230a1 update changelog 2023-07-01 14:17:42 +06:00
b81308da8b get back default filters for the queries but fix them 2023-07-01 13:53:26 +06:00
0441b53da2 all query triggers got null default subcontext filter 2023-07-01 03:46:29 +06:00
4853a5b3ad improve docs of onInlineQuery 2023-06-30 22:46:58 +06:00
40a0d2c37d fixes in default filters of updates 2023-06-30 22:42:48 +06:00
2e815a4c37 #773 fix, improvements in updates handling 2023-06-30 16:35:14 +06:00
81ed820602 Migrate onto 9.0.0 and update dependenices
Update libs.versions.toml

Update CHANGELOG.md

Update gradle.properties

Update CHANGELOG.md
2023-06-30 15:22:21 +06:00
b3a657b7d6 make bots username nullable 2023-06-30 14:11:28 +06:00
8247e7c69c add backward compatibility change 2023-06-30 14:11:28 +06:00
67b7472868 Update libs.versions.toml 2023-06-30 02:55:27 +06:00
13e4740d0a improve Update.sourceChat 2023-06-29 13:45:08 +06:00
48db305541 start 8.1.1 2023-06-29 12:18:44 +06:00
6f512a144c Merge pull request #766 from InsanusMokrassar/8.1.0
8.1.0
2023-06-19 22:48:50 +06:00
cf46139bef remove redundant ClassCastsExcluded 2023-06-19 22:14:20 +06:00
14a583e154 update microutils 2023-06-19 21:46:27 +06:00
5b6753c484 small fill of changelog 2023-06-16 14:43:59 +06:00
f153b31464 improve class casts including filtering 2023-06-16 13:50:34 +06:00
6f60ecbf2e fill changelog 2023-06-16 12:14:12 +06:00
9c57ba4da7 rename new Tg methods 2023-06-16 12:12:50 +06:00
d84d982eb4 Merge pull request #768 from klimatov/makeTgDeepLink
added support for the tg:// format for deep links
2023-06-16 12:09:01 +06:00
Pavel Klimatov
2f6f40362a added support for the tg:// format for deep links 2023-06-16 01:54:06 +07:00
e15b18fbcf upgrade up to 8.1.0 2023-06-12 12:34:36 +06:00
ad5cc6ade6 add excluding of impls 2023-06-12 12:25:43 +06:00
6b94215a7c 8.0.2 2023-06-12 10:42:54 +06:00
9c98411bcb Update README.md 2023-06-10 18:16:01 +06:00
b235ab1c28 update dokka version 2023-06-09 12:05:29 +06:00
d4e11494e8 update kdocs of buttons creation shortcuts 2023-06-04 12:38:40 +06:00
e6dbf2bde9 Merge pull request #760 from InsanusMokrassar/8.0.1
8.0.1
2023-06-03 00:58:09 +06:00
141 changed files with 3057 additions and 1109 deletions

View File

@@ -5,6 +5,9 @@ on: [pull_request, issues]
jobs: jobs:
greeting: greeting:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps: steps:
- uses: actions/first-interaction@v1 - uses: actions/first-interaction@v1
with: with:

View File

@@ -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: 11 java-version: 17
- name: Build - name: Build
run: ./gradlew dokkaHtmlMultiModule run: ./gradlew dokkaHtmlMultiModule
- name: Publish KDocs - name: Publish KDocs

View File

@@ -7,9 +7,9 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 17
- name: Setup LibCurl - name: Setup LibCurl
run: sudo apt install -y libcurl4-openssl-dev run: sudo apt update && sudo apt install -y libcurl4-openssl-dev
- name: Rewrite version - name: Rewrite version
run: | run: |
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`" branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
@@ -22,9 +22,10 @@ jobs:
run: ./gradlew build run: ./gradlew build
- name: Publish to Gitea - name: Publish to Gitea
continue-on-error: true continue-on-error: true
run: ./gradlew publishAllPublicationsToGiteaRepository run: ./gradlew publishAllPublicationsToInmoNexusRepository
env: env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} INMONEXUS_USER: ${{ secrets.INMONEXUS_USER }}
INMONEXUS_PASSWORD: ${{ secrets.INMONEXUS_PASSWORD }}
- name: Publish to GithubPackages - name: Publish to GithubPackages
continue-on-error: true continue-on-error: true
run: ./gradlew publishAllPublicationsToGithubPackagesRepository --no-parallel run: ./gradlew publishAllPublicationsToGithubPackagesRepository --no-parallel

View File

@@ -1,5 +1,121 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 9.4.2
* `Version`:
* `Serialization`: `1.6.1` -> `1.6.2`
* `Ktor`: `2.3.6` -> `2.3.7`
* `MicroUtils`: `0.20.15` -> `0.20.19`
* `UUID`: `0.8.1` -> `0.8.2`
## 9.4.1
* Replace warning about two bots from `LongPolling` to `DefaultKtorRequestsExecutor`
## 9.4.0
* `Version`:
* `Kotlin`: `1.9.20` -> `1.9.21`
* `Serialization`: `1.6.0` -> `1.6.1`
* `Ktor`: `2.3.5` -> `2.3.6`
* `MicroUtils`: `0.20.12` -> `0.20.15`
## 9.3.0
This release become possible thanks to [Anton Lakotka](https://youtrack.jetbrains.com/users/anton.lakotka)
**THIS RELEASE CONTAINS UPDATES UP TO RELEASE CANDIDATES VERSIONS**
**UPDATE MAY HAVE BREAKING CHANGES**
**SINCE THIS UPDATE IT WILL BE REQUIRED TO USE JDK 17+ FOR DEVELOPMENT**
* `Version`:
* `Kotlin`: `1.8.22` -> `1.9.20`
* `Serialization`: `1.5.1` -> `1.6.0`
* `KorLibs`: `4.0.3` -> `4.0.10`
* `UUID`: `0.7.1` -> `0.8.1`
* `Ktor`: `2.3.4` -> `2.3.5`
* `MicroUtils`: `0.19.9` -> `0.20.12`
## 9.2.4
* `Utils`:
* New extensions `*.parseCommandsWithNamedArgs`
* `BehaviourBuilder`:
* In expectaters and triggers of `commands` add `*WithNamedArgs` variants
* In expectaters and triggers of `commands` add opportunity to use custom separator
## 9.2.3
* `Core`:
* Fix in `VoiceContent#createResend`
## 9.2.2
* `Core`:
* Fix of [#793](https://github.com/InsanusMokrassar/ktgbotapi/issues/793): Add `PreviewChat`
## 9.2.1
* `Version`:
* `Ktor`: `2.3.3` -> `2.3.4`
* `Core`:
* All `ChatMember` inheritors have fixes `status` field
## 9.2.0
**Add support of [Telegram Bots API 6.9](https://core.telegram.org/bots/api-changelog#september-22-2023)**
* Rename `ChatAdministratorRightsImpl` -> `ChatCommonAdministratorRights`
* All the request chat keyboards has changed their parameters `ChatAdministratorRights` to `ChatCommonAdministratorRights`
## 9.1.2
* `Core`:
* Fix of `MessageContent` serialization
## 9.1.1
* `Core`:
* Potential fix of incorrect parsing in `RawMessageEntity`
## 9.1.0
**This update contains adding of [Telegram Bot API 6.8](https://core.telegram.org/bots/api-changelog#august-18-2023) support**
* `Version`:
* `Coroutines`: `1.7.2` -> `1.7.3`
* `Ktor`: `2.3.2` -> `2.3.3`
* `MicroUtils`: `0.19.7` -> `0.19.9`
## 9.0.0
**THIS UPDATE CONTAINS BREAKING CHANGES: USERNAMES OF BOTS NOW BECAME NULLABLE**
* `Version`:
* `Coroutines`: `1.6.4` -> `1.7.1`
* `Ktor`: `2.3.1` -> `2.3.2`
* `MicroUtils`: `0.19.4` -> `0.19.7`
* `Core`:
* **All bots now have nullable usernames just like common users ([#772](https://github.com/InsanusMokrassar/ktgbotapi/issues/772))**
* Decrease possible errors in updates handling by additional handling of update deserialization wrapping ([#773](https://github.com/InsanusMokrassar/ktgbotapi/issues/773))
* New interface `GetUpdatesRequest`. You may implement it to show default telegram bot ktor executor that this
request is an updates request and should be handled in a different way
* Now it is possible to get raw updates with `GetUpdatesRaw` request
* `Utils`:
* Improve extension `Update.sourceChat` to add opportunity to select some chats by logic different with the default
## 8.1.0
**PARTIALLY BREAKING CHANGES: Exclude `.*Impl` classcasts from `ClassCastsNew`**
* `Version`:
* `MicroUtils`: `0.19.2` -> `0.19.4`
* `Utils`:
* Add deep links formatting for internal `tg://` prefix (thanks to [@klimatov](https://github.com/klimatov))
* Exclude `.*Impl` classcasts from `ClassCastsNew`
## 8.0.1 ## 8.0.1
* `Version`: * `Version`:

View File

@@ -1,6 +1,6 @@
# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.7-blue)](https://core.telegram.org/bots/api-changelog#april-21-2023) # TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.9-blue)](https://core.telegram.org/bots/api-changelog#september-22-2023)
| Docs | [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue&logo=kotlin)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Bookstack&message=Tutorial&color=blue&logo=bookstack)](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) | | Docs | [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue&logo=kotlin)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Mk&message=Docs&color=blue&logo=mkdocs)](https://docs.inmo.dev/tgbotapi/index.html) |
|:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| |:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Useful repos | [![Create bot](https://img.shields.io/static/v1?label=Github&message=Template&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![Examples](https://img.shields.io/static/v1?label=Github&message=Examples&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) | | Useful repos | [![Create bot](https://img.shields.io/static/v1?label=Github&message=Template&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![Examples](https://img.shields.io/static/v1?label=Github&message=Examples&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) |
| Misc | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue&logo=google-sheets)](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) | | Misc | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue&logo=google-sheets)](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) |

View File

@@ -16,6 +16,7 @@ buildscript {
plugins { plugins {
alias(libs.plugins.kotlin.dokka) alias(libs.plugins.kotlin.dokka)
alias(libs.plugins.versions)
} }
// temporal crutch until legacy tests will be stabled or legacy target will be removed // temporal crutch until legacy tests will be stabled or legacy target will be removed
@@ -24,7 +25,7 @@ allprojects {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
google() google()
maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" } maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
} }
if (it != rootProject.findProject("docs")) { if (it != rootProject.findProject("docs")) {
tasks.whenTaskAdded { task -> tasks.whenTaskAdded { task ->

View File

@@ -54,8 +54,8 @@ Object callback = {
skipDeprecated.set(true) skipDeprecated.set(true)
sourceLink { sourceLink {
localDirectory.set(file("./")) localDirectory.set(file("../"))
remoteUrl.set(new URL("https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/")) remoteUrl.set(new URL("https://github.com/InsanusMokrassar/ktgbotapi/tree/master"))
remoteLineSuffix.set("#L") remoteLineSuffix.set("#L")
} }
} }

View File

@@ -6,4 +6,4 @@ kotlin.incremental=true
kotlin.incremental.js=true kotlin.incremental.js=true
library_group=dev.inmo library_group=dev.inmo
library_version=8.0.1 library_version=9.4.2

View File

@@ -1,22 +1,25 @@
[versions] [versions]
kotlin = "1.8.21" kotlin = "1.9.21"
kotlin-serialization = "1.5.1" kotlin-serialization = "1.6.2"
kotlin-coroutines = "1.6.4" kotlin-coroutines = "1.7.3"
javax-activation = "1.1.1" javax-activation = "1.1.1"
korlibs = "4.0.3" korlibs = "4.0.10"
uuid = "0.7.1" uuid = "0.8.2"
ktor = "2.3.1" ktor = "2.3.7"
ksp = "1.8.21-1.0.11" ksp = "1.9.21-1.0.15"
kotlin-poet = "1.14.2" kotlin-poet = "1.15.3"
microutils = "0.19.2" microutils = "0.20.19"
kslog = "1.3.1"
versions = "0.50.0"
github-release-plugin = "2.4.1" github-release-plugin = "2.4.1"
dokka = "1.8.10" dokka = "1.9.10"
[libraries] [libraries]
@@ -52,6 +55,8 @@ microutils-languageCodes = { module = "dev.inmo:micro_utils.language_codes", ver
microutils-ktor-common = { module = "dev.inmo:micro_utils.ktor.common", version.ref = "microutils" } microutils-ktor-common = { module = "dev.inmo:micro_utils.ktor.common", version.ref = "microutils" }
microutils-fsm-common = { module = "dev.inmo:micro_utils.fsm.common", version.ref = "microutils" } microutils-fsm-common = { module = "dev.inmo:micro_utils.fsm.common", version.ref = "microutils" }
kslog = { module = "dev.inmo:kslog", version.ref = "kslog" }
# ksp dependencies # ksp dependencies
kotlin-poet = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin-poet" } kotlin-poet = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin-poet" }
@@ -71,3 +76,4 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } kotlin-dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
versions = { id = "com.github.ben-manes.versions", version.ref = "versions" }

View File

@@ -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.6.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip

View File

@@ -5,7 +5,7 @@ kotlin {
jvm { jvm {
compilations.main { compilations.main {
kotlinOptions { kotlinOptions {
jvmTarget = "1.8" jvmTarget = "17"
} }
} }
} }
@@ -15,6 +15,7 @@ kotlin {
} }
linuxX64() linuxX64()
mingwX64() mingwX64()
linuxArm64()
sourceSets { sourceSets {
commonMain { commonMain {
@@ -40,10 +41,18 @@ kotlin {
implementation libs.kotlin.test.junit implementation libs.kotlin.test.junit
} }
} }
all {
languageSettings {
optIn('dev.inmo.tgbotapi.utils.RiskFeature')
optIn('dev.inmo.tgbotapi.utils.PreviewFeature')
optIn('dev.inmo.micro_utils.common.Warning')
optIn('dev.inmo.micro_utils.common.PreviewFeature')
}
}
} }
} }
java { java {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_17
} }

View File

@@ -1,8 +1,7 @@
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
task javadocsJar(type: Jar) { task javadocsJar(type: Jar) {
archiveClassifier.convention("javadoc") archiveClassifier = 'javadoc'
archiveClassifier.set("javadoc")
} }
publishing { publishing {
@@ -20,22 +19,22 @@ publishing {
} }
developers { developers {
developer { developer {
id = "InsanusMokrassar" id = "InsanusMokrassar"
name = "Ovsiannikov Aleksei" name = "Ovsiannikov Aleksei"
email = "ovsyannikov.alexey95@gmail.com" email = "ovsyannikov.alexey95@gmail.com"
} }
} }
licenses { licenses {
license { license {
name = "Apache Software License 2.0" name = "Apache Software License 2.0"
url = "https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE" url = "https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"
} }
} }
} }
repositories { repositories {
@@ -43,58 +42,77 @@ publishing {
maven { maven {
name = "GithubPackages" name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI") url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
credentials { credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER') 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') password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
} }
} }
} }
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) { if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
maven { maven {
name = "Gitea" name = "InmoNexus"
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven") url = uri("https://nexus.inmo.dev/repository/maven-releases/")
credentials(HttpHeaderCredentials) { credentials {
name = "Authorization" username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN') password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
} }
authentication {
header(HttpHeaderAuthentication)
}
} }
} }
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) { if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven { maven {
name = "sonatype" name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials { credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER') 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') password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
} }
} }
} }
} }
} }
} }
if (project.hasProperty("signing.gnupg.keyName")) { if (project.hasProperty("signing.gnupg.keyName")) {
apply plugin: 'signing' apply plugin: 'signing'
signing { signing {
useGpgCmd() useGpgCmd()
sign publishing.publications sign publishing.publications
} }
task signAll { task signAll {
tasks.withType(Sign).forEach { tasks.withType(Sign).forEach {
dependsOn(it) dependsOn(it)
} }
} }
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest$pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin$pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
} }

View File

@@ -1 +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":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}} {"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":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}

View File

@@ -0,0 +1,27 @@
package dev.inmo.tgbotapi.extensions.api
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.GetUpdates
import dev.inmo.tgbotapi.requests.GetUpdatesRaw
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.update.abstracts.Update
suspend fun TelegramBot.getRawUpdates(
offset: UpdateIdentifier? = null,
limit: Int = getUpdatesLimit.last,
timeout: Seconds? = null,
allowed_updates: List<String>? = ALL_UPDATES_LIST
) = execute(
GetUpdatesRaw(
offset, limit, timeout, allowed_updates
)
)
suspend fun TelegramBot.getRawUpdates(
lastUpdate: Update,
limit: Int = getUpdatesLimit.last,
timeout: Seconds? = null,
allowed_updates: List<String>? = ALL_UPDATES_LIST
) = getRawUpdates(
lastUpdate.updateId + 1, limit, timeout, allowed_updates
)

View File

@@ -2,17 +2,17 @@ package dev.inmo.tgbotapi.extensions.api.bot
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.bot.SetMyDefaultAdministratorRights import dev.inmo.tgbotapi.requests.bot.SetMyDefaultAdministratorRights
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRightsImpl import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights
suspend fun TelegramBot.setMyDefaultAdministratorRights( suspend fun TelegramBot.setMyDefaultAdministratorRights(
rights: ChatAdministratorRightsImpl, rights: ChatCommonAdministratorRights,
forChannels: Boolean? = null forChannels: Boolean? = null
) = execute(SetMyDefaultAdministratorRights(rights, forChannels)) ) = execute(SetMyDefaultAdministratorRights(rights, forChannels))
suspend fun TelegramBot.setMyDefaultAdministratorRightsForChannels( suspend fun TelegramBot.setMyDefaultAdministratorRightsForChannels(
rights: ChatAdministratorRightsImpl rights: ChatCommonAdministratorRights
) = setMyDefaultAdministratorRights(rights, forChannels = true) ) = setMyDefaultAdministratorRights(rights, forChannels = true)
suspend fun TelegramBot.setMyDefaultAdministratorRightsForGroupsAndSupergroups( suspend fun TelegramBot.setMyDefaultAdministratorRightsForGroupsAndSupergroups(
rights: ChatAdministratorRightsImpl rights: ChatCommonAdministratorRights
) = setMyDefaultAdministratorRights(rights, forChannels = false) ) = setMyDefaultAdministratorRights(rights, forChannels = false)

View File

@@ -0,0 +1,21 @@
package dev.inmo.tgbotapi.extensions.api.chat.forum
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.forum.UnpinAllForumTopicMessages
import dev.inmo.tgbotapi.requests.chat.forum.UnpinAllGeneralForumTopicMessages
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.ForumTopic
import dev.inmo.tgbotapi.types.MessageThreadId
import dev.inmo.tgbotapi.types.chat.Chat
suspend fun TelegramBot.unpinAllGeneralForumTopicMessages(
chatId: ChatIdentifier
) = execute(
UnpinAllGeneralForumTopicMessages(
chatId
)
)
suspend fun TelegramBot.unpinAllGeneralForumTopicMessages(
chat: Chat
) = unpinAllGeneralForumTopicMessages(chat.id)

View File

@@ -0,0 +1,157 @@
package dev.inmo.tgbotapi.extensions.api.chat.members
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.members.PromoteChannelAdministrator
import dev.inmo.tgbotapi.requests.chat.members.PromoteChatMember
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.PublicChat
import dev.inmo.tgbotapi.types.chat.User
suspend fun TelegramBot.promoteChannelAdministrator(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canPostMessages: Boolean? = null,
canEditMessages: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = execute(
PromoteChannelAdministrator(
chatId = chatId,
userId = userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = canPostMessages,
canEditMessages = canEditMessages,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
)
)
suspend fun TelegramBot.promoteChannelAdministrator(
chat: PublicChat,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canPostMessages: Boolean? = null,
canEditMessages: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = promoteChannelAdministrator(
chat.id,
userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = canPostMessages,
canEditMessages = canEditMessages,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
)
suspend fun TelegramBot.promoteChannelAdministrator(
chatId: IdChatIdentifier,
user: User,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canPostMessages: Boolean? = null,
canEditMessages: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = promoteChannelAdministrator(
chatId,
user.id,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = canPostMessages,
canEditMessages = canEditMessages,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
)
suspend fun TelegramBot.promoteChannelAdministrator(
chat: PublicChat,
user: User,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canPostMessages: Boolean? = null,
canEditMessages: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = promoteChannelAdministrator(
chat.id,
user.id,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = canPostMessages,
canEditMessages = canEditMessages,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
)

View File

@@ -0,0 +1,116 @@
package dev.inmo.tgbotapi.extensions.api.chat.members
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.members.PromoteChatMember
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.PublicChat
import dev.inmo.tgbotapi.types.chat.User
suspend fun TelegramBot.promoteChatAdministrator(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
) = execute(
PromoteChatMember(
chatId,
userId,
untilDate,
isAnonymous,
canChangeInfo,
canDeleteMessages,
canInviteUsers,
canRestrictMembers,
canPromoteMembers,
canManageVideoChats,
canManageChat
)
)
suspend fun TelegramBot.promoteChatAdministrator(
chat: PublicChat,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
) = promoteChatAdministrator(
chat.id,
userId,
untilDate,
isAnonymous,
canChangeInfo,
canDeleteMessages,
canInviteUsers,
canRestrictMembers,
canPromoteMembers,
canManageVideoChats,
canManageChat
)
suspend fun TelegramBot.promoteChatAdministrator(
chatId: IdChatIdentifier,
user: User,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
) = promoteChatAdministrator(
chatId,
user.id,
untilDate,
isAnonymous,
canChangeInfo,
canDeleteMessages,
canInviteUsers,
canRestrictMembers,
canPromoteMembers,
canManageVideoChats,
canManageChat
)
suspend fun TelegramBot.promoteChatAdministrator(
chat: PublicChat,
user: User,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
) = promoteChatAdministrator(
chat.id,
user.id,
untilDate,
isAnonymous,
canChangeInfo,
canDeleteMessages,
canInviteUsers,
canRestrictMembers,
canPromoteMembers,
canManageVideoChats,
canManageChat
)

View File

@@ -1,14 +1,13 @@
package dev.inmo.tgbotapi.extensions.api.chat.members package dev.inmo.tgbotapi.extensions.api.chat.members
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.members.PromoteChatMember import dev.inmo.tgbotapi.requests.chat.members.PromoteChatMember
import dev.inmo.tgbotapi.types.IdChatIdentifier import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.PublicChat import dev.inmo.tgbotapi.types.chat.PublicChat
import dev.inmo.tgbotapi.types.chat.User import dev.inmo.tgbotapi.types.chat.User
@Warning("This method is too common. Use it with caution")
suspend fun TelegramBot.promoteChatMember( suspend fun TelegramBot.promoteChatMember(
chatId: ChatIdentifier, chatId: ChatIdentifier,
userId: UserId, userId: UserId,
@@ -24,27 +23,34 @@ suspend fun TelegramBot.promoteChatMember(
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null, canManageChat: Boolean? = null,
canManageTopics: Boolean? = null canManageTopics: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = execute( ) = execute(
PromoteChatMember( PromoteChatMember(
chatId, chatId = chatId,
userId, userId = userId,
untilDate, untilDate = untilDate,
isAnonymous, isAnonymous = isAnonymous,
canChangeInfo, canChangeInfo = canChangeInfo,
canPostMessages, canPostMessages = canPostMessages,
canEditMessages, canEditMessages = canEditMessages,
canDeleteMessages, canDeleteMessages = canDeleteMessages,
canInviteUsers, canInviteUsers = canInviteUsers,
canRestrictMembers, canRestrictMembers = canRestrictMembers,
canPinMessages, canPinMessages = canPinMessages,
canPromoteMembers, canPromoteMembers = canPromoteMembers,
canManageVideoChats, canManageVideoChats = canManageVideoChats,
canManageChat, canManageChat = canManageChat,
canManageTopics canManageTopics = canManageTopics,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
) )
) )
@Warning("This method is too common. Use it with caution")
suspend fun TelegramBot.promoteChatMember( suspend fun TelegramBot.promoteChatMember(
chat: PublicChat, chat: PublicChat,
userId: UserId, userId: UserId,
@@ -60,25 +66,32 @@ suspend fun TelegramBot.promoteChatMember(
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null, canManageChat: Boolean? = null,
canManageTopics: Boolean? = null canManageTopics: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = promoteChatMember( ) = promoteChatMember(
chat.id, chat.id,
userId, userId,
untilDate, untilDate = untilDate,
isAnonymous, isAnonymous = isAnonymous,
canChangeInfo, canChangeInfo = canChangeInfo,
canPostMessages, canPostMessages = canPostMessages,
canEditMessages, canEditMessages = canEditMessages,
canDeleteMessages, canDeleteMessages = canDeleteMessages,
canInviteUsers, canInviteUsers = canInviteUsers,
canRestrictMembers, canRestrictMembers = canRestrictMembers,
canPinMessages, canPinMessages = canPinMessages,
canPromoteMembers, canPromoteMembers = canPromoteMembers,
canManageVideoChats, canManageVideoChats = canManageVideoChats,
canManageChat, canManageChat = canManageChat,
canManageTopics canManageTopics = canManageTopics,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
) )
@Warning("This method is too common. Use it with caution")
suspend fun TelegramBot.promoteChatMember( suspend fun TelegramBot.promoteChatMember(
chatId: IdChatIdentifier, chatId: IdChatIdentifier,
user: User, user: User,
@@ -94,25 +107,32 @@ suspend fun TelegramBot.promoteChatMember(
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null, canManageChat: Boolean? = null,
canManageTopics: Boolean? = null canManageTopics: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = promoteChatMember( ) = promoteChatMember(
chatId, chatId,
user.id, user.id,
untilDate, untilDate = untilDate,
isAnonymous, isAnonymous = isAnonymous,
canChangeInfo, canChangeInfo = canChangeInfo,
canPostMessages, canPostMessages = canPostMessages,
canEditMessages, canEditMessages = canEditMessages,
canDeleteMessages, canDeleteMessages = canDeleteMessages,
canInviteUsers, canInviteUsers = canInviteUsers,
canRestrictMembers, canRestrictMembers = canRestrictMembers,
canPinMessages, canPinMessages = canPinMessages,
canPromoteMembers, canPromoteMembers = canPromoteMembers,
canManageVideoChats, canManageVideoChats = canManageVideoChats,
canManageChat, canManageChat = canManageChat,
canManageTopics canManageTopics = canManageTopics,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
) )
@Warning("This method is too common. Use it with caution")
suspend fun TelegramBot.promoteChatMember( suspend fun TelegramBot.promoteChatMember(
chat: PublicChat, chat: PublicChat,
user: User, user: User,
@@ -128,21 +148,27 @@ suspend fun TelegramBot.promoteChatMember(
canPromoteMembers: Boolean? = null, canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null, canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null, canManageChat: Boolean? = null,
canManageTopics: Boolean? = null canManageTopics: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = promoteChatMember( ) = promoteChatMember(
chat.id, chat.id,
user.id, user.id,
untilDate, untilDate = untilDate,
isAnonymous, isAnonymous = isAnonymous,
canChangeInfo, canChangeInfo = canChangeInfo,
canPostMessages, canPostMessages = canPostMessages,
canEditMessages, canEditMessages = canEditMessages,
canDeleteMessages, canDeleteMessages = canDeleteMessages,
canInviteUsers, canInviteUsers = canInviteUsers,
canRestrictMembers, canRestrictMembers = canRestrictMembers,
canPinMessages, canPinMessages = canPinMessages,
canPromoteMembers, canPromoteMembers = canPromoteMembers,
canManageVideoChats, canManageVideoChats = canManageVideoChats,
canManageChat, canManageChat = canManageChat,
canManageTopics canManageTopics = canManageTopics,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
) )

View File

@@ -0,0 +1,133 @@
package dev.inmo.tgbotapi.extensions.api.chat.members
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.members.PromoteChatMember
import dev.inmo.tgbotapi.requests.chat.members.PromoteSupergroupAdministrator
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.PublicChat
import dev.inmo.tgbotapi.types.chat.User
suspend fun TelegramBot.promoteSupergroupAdministrator(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canManageTopics: Boolean? = null,
) = execute(
PromoteSupergroupAdministrator(
chatId = chatId,
userId = userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = canPinMessages,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = canManageTopics
)
)
suspend fun TelegramBot.promoteSupergroupAdministrator(
chat: PublicChat,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canManageTopics: Boolean? = null,
) = promoteSupergroupAdministrator(
chat.id,
userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = canPinMessages,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = canManageTopics
)
suspend fun TelegramBot.promoteSupergroupAdministrator(
chatId: IdChatIdentifier,
user: User,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canManageTopics: Boolean? = null,
) = promoteSupergroupAdministrator(
chatId,
user.id,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = canPinMessages,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = canManageTopics
)
suspend fun TelegramBot.promoteSupergroupAdministrator(
chat: PublicChat,
user: User,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canManageTopics: Boolean? = null,
) = promoteSupergroupAdministrator(
chat.id,
user.id,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = canPinMessages,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = canManageTopics
)

View File

@@ -13,6 +13,8 @@ kotlin {
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api project(":tgbotapi.core")
api project(":tgbotapi.utils")
api project(":tgbotapi.behaviour_builder") api project(":tgbotapi.behaviour_builder")
api libs.microutils.fsm.common api libs.microutils.fsm.common
} }

View File

@@ -13,7 +13,8 @@ kotlin {
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api project(":tgbotapi.utils") api project(path: ':tgbotapi.core')
api project(path: ':tgbotapi.utils')
} }
} }
} }

View File

@@ -3,6 +3,10 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.doWithRegistration import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.doWithRegistration
import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.extensions.TelegramBotCommandsDefaults
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgsSources
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithNamedArgs
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.BotCommand import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
@@ -79,35 +83,54 @@ fun Flow<CommonMessage<TextContent>>.requireCommandsWithoutParams() = filter {
} }
/** /**
* Map the commands with their arguments and source messages * Uses [parseCommandsWithArgsSources] on incoming text sources and map them with [CommonMessage]
*/ */
fun Flow<CommonMessage<TextContent>>.commandsWithParams(): Flow<Pair<CommonMessage<TextContent>, List<Pair<BotCommandTextSource, Array<TextSource>>>>> = mapNotNull { fun Flow<CommonMessage<TextContent>>.commandsWithParams(): Flow<Pair<CommonMessage<TextContent>, List<Pair<BotCommandTextSource, Array<TextSource>>>>> = mapNotNull {
var currentCommandTextSource: BotCommandTextSource? = null it to it.content.textSources.parseCommandsWithArgsSources().toList()
val currentArgs = mutableListOf<TextSource>()
val result = mutableListOf<Pair<BotCommandTextSource, Array<TextSource>>>()
fun addCurrentCommandToResult() {
currentCommandTextSource ?.let {
result.add(it to currentArgs.toTypedArray())
currentArgs.clear()
}
}
it.content.textSources.forEach {
it.ifBotCommandTextSource {
addCurrentCommandToResult()
currentCommandTextSource = it
return@forEach
}
currentArgs.add(it)
}
addCurrentCommandToResult()
result.toList().takeIf { it.isNotEmpty() } ?.let { result ->
it to result
}
} }
/**
* Uses [parseCommandsWithArgs] on incoming text sources and map them with [CommonMessage]
*/
fun Flow<CommonMessage<TextContent>>.commandsWithArgs(
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, Array<String>>>>> = mapNotNull {
val commandsWithArgs = it.content.textSources.parseCommandsWithArgs(argsSeparator).toList().ifEmpty {
return@mapNotNull null
}
it to commandsWithArgs
}
/**
* Uses [parseCommandsWithArgs] on incoming text sources and map them with [CommonMessage]
*/
fun Flow<CommonMessage<TextContent>>.commandsWithArgs(
argsSeparator: String
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, Array<String>>>>> = commandsWithArgs(Regex(argsSeparator))
/**
* Uses [parseCommandsWithNamedArgs] on incoming text sources and map them with [CommonMessage]
*/
fun Flow<CommonMessage<TextContent>>.commandsWithNamedArgs(
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, List<Pair<String, String>>>>>> = mapNotNull {
val commandsWithArgs = it.content.textSources.parseCommandsWithNamedArgs(argsSeparator, nameArgSeparator).toList().ifEmpty {
return@mapNotNull null
}
it to commandsWithArgs
}
/**
* Uses [parseCommandsWithNamedArgs] on incoming text sources and map them with [CommonMessage]
*/
fun Flow<CommonMessage<TextContent>>.commandsWithNamedArgs(
argsSeparator: String,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, List<Pair<String, String>>>>>> = commandsWithNamedArgs(Regex(argsSeparator), nameArgSeparator)
/** /**
* Flat [commandsWithParams]. Each [Pair] of [BotCommandTextSource] and its [Array] of arg text sources will * Flat [commandsWithParams]. Each [Pair] of [BotCommandTextSource] and its [Array] of arg text sources will
* be associated with its source message * be associated with its source message

View File

@@ -62,6 +62,10 @@ suspend fun BehaviourContext.waitText(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<TextContent>() ) = waitContent(initRequest, errorFactory).mapContent<TextContent>()
suspend fun BehaviourContext.waitStory(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<StoryContent>()
suspend fun BehaviourContext.waitVenue( suspend fun BehaviourContext.waitVenue(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }

View File

@@ -74,6 +74,10 @@ suspend fun BehaviourContext.waitTextMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextContent>() ) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextContent>()
suspend fun BehaviourContext.waitStoryMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StoryContent>()
suspend fun BehaviourContext.waitVenueMessage( suspend fun BehaviourContext.waitVenueMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }

View File

@@ -174,6 +174,25 @@ suspend fun BehaviourContext.waitWriteAccessAllowed(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<WriteAccessAllowed>(initRequest, errorFactory) ) = waitEvents<WriteAccessAllowed>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedFromRequest(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<WriteAccessAllowed.FromRequest>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedFromAttachmentMenu(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<WriteAccessAllowed.FromAttachmentMenu>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedFromWebAppLink(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<WriteAccessAllowed.FromWebAppLink>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedOther(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEvents<WriteAccessAllowed.Other>(initRequest, errorFactory)
suspend fun BehaviourContext.waitChatSharedRequest( suspend fun BehaviourContext.waitChatSharedRequest(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,

View File

@@ -171,6 +171,22 @@ suspend fun BehaviourContext.waitWriteAccessAllowedEventsMessages(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<WriteAccessAllowed>(initRequest, errorFactory) ) = waitEventsMessages<WriteAccessAllowed>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedFromRequestEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<WriteAccessAllowed.FromRequest>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedFromAttachmentMenuEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<WriteAccessAllowed.FromAttachmentMenu>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedFromWebAppLinkEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<WriteAccessAllowed.FromWebAppLink>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWriteAccessAllowedOtherEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<WriteAccessAllowed.Other>(initRequest, errorFactory)
suspend fun BehaviourContext.waitChatSharedRequestEventsMessages( suspend fun BehaviourContext.waitChatSharedRequestEventsMessages(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,

View File

@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.filters
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceUser
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated
@@ -15,7 +16,9 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
* Allow only events from the same chat as base [Message] * Allow only events from the same chat as base [Message]
*/ */
val MessageFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, Message, Update> = { message, update -> val MessageFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, Message, Update> = { message, update ->
update.sourceChat() ?.id == message.chat.id update.sourceChat() ?.let {
it.id == message.chat.id
} != false
} }
/** /**
* Allow only events from the same chat as base [List] of [Message] * Allow only events from the same chat as base [List] of [Message]
@@ -29,31 +32,41 @@ val MessagesFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, List<Mess
* Allow only updates from the same user as base [CallbackQuery.user] * Allow only updates from the same user as base [CallbackQuery.user]
*/ */
val CallbackQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, CallbackQuery, Update> = { query, update -> val CallbackQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, CallbackQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.user.id update.sourceUser() ?.let {
it.id == query.user.id
} != false
} }
/** /**
* Allow only updates from the same user as base [ShippingQuery.user] * Allow only updates from the same user as base [ShippingQuery.user]
*/ */
val ShippingQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, ShippingQuery, Update> = { query, update -> val ShippingQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, ShippingQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.user.id update.sourceUser() ?.let {
it.id == query.user.id
} != false
} }
/** /**
* Allow only updates from the same user as base [ShippingQuery.user] * Allow only updates from the same user as base [ShippingQuery.user]
*/ */
val PreCheckoutQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, PreCheckoutQuery, Update> = { query, update -> val PreCheckoutQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, PreCheckoutQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.user.id update.sourceUser() ?.let {
it.id == query.user.id
} != false
} }
/** /**
* Allow only updates from the same user as base [InlineQuery.from] * Allow only updates from the same user as base [InlineQuery.from]
*/ */
val InlineQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, InlineQuery, Update> = { query, update -> val InlineQueryFilterByUser: BehaviourContextAndTwoTypesReceiver<Boolean, InlineQuery, Update> = { query, update ->
update.sourceChat() ?.id == query.from.id update.sourceUser() ?.let {
it.id == query.user.id
} != false
} }
/** /**
* Allow only events from the same chat as base [ChatMemberUpdated] * Allow only events from the same chat as base [ChatMemberUpdated]
*/ */
val ChatMemberUpdatedFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, ChatMemberUpdated, Update> = { updated, update -> val ChatMemberUpdatedFilterByChat: BehaviourContextAndTwoTypesReceiver<Boolean, ChatMemberUpdated, Update> = { updated, update ->
update.sourceChat() ?.id == updated.chat.id update.sourceChat() ?.let {
it.id == updated.chat.id
} != false
} }
/** /**
* Allow only events from the same chat as base [ChatMemberUpdated] * Allow only events from the same chat as base [ChatMemberUpdated]

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.ChatJoinRequestFilterByChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatChatJoinRequestMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatChatJoinRequestMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
@@ -25,7 +24,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
*/ */
suspend fun <BC : BehaviourContext> BC.onChatJoinRequest( suspend fun <BC : BehaviourContext> BC.onChatJoinRequest(
initialFilter: SimpleFilter<ChatJoinRequest>? = null, initialFilter: SimpleFilter<ChatJoinRequest>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatJoinRequest, Update>? = ChatJoinRequestFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatJoinRequest, Update>? = null,
markerFactory: MarkerFactory<in ChatJoinRequest, Any> = ByChatChatJoinRequestMarkerFactory, markerFactory: MarkerFactory<in ChatJoinRequest, Any> = ByChatChatJoinRequestMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatJoinRequest> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatJoinRequest>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {

View File

@@ -11,7 +11,9 @@ 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.behaviour_builder.utils.times import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams import dev.inmo.tgbotapi.extensions.utils.extensions.TelegramBotCommandsDefaults
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithNamedArgs
import dev.inmo.tgbotapi.types.BotCommand import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextMessage import dev.inmo.tgbotapi.types.message.content.TextMessage
@@ -22,7 +24,7 @@ internal suspend fun <BC : BehaviourContext> BC.commandUncounted(
commandRegex: Regex, commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onText( ): Job = onText(
@@ -49,7 +51,7 @@ suspend fun <BC : BehaviourContext> BC.command(
commandRegex: Regex, commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = runCatchingSafely { ): Job = runCatchingSafely {
@@ -78,7 +80,7 @@ suspend fun <BC : BehaviourContext> BC.command(
command: String, command: String,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = command(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = command(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -87,7 +89,7 @@ suspend fun <BC : BehaviourContext> BC.command(
botCommand: BotCommand, botCommand: BotCommand,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = command(botCommand.command, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = command(botCommand.command, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -96,7 +98,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
commandRegex: Regex, commandRegex: Regex,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = command(commandRegex, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = command(commandRegex, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -105,7 +107,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
command: String, command: String,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -114,7 +116,7 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
botCommand: BotCommand, botCommand: BotCommand,
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onCommand(botCommand.command, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onCommand(botCommand.command, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -122,8 +124,9 @@ suspend fun <BC : BehaviourContext> BC.onCommand(
suspend fun <BC : BehaviourContext> BC.commandWithArgs( suspend fun <BC : BehaviourContext> BC.commandWithArgs(
commandRegex: Regex, commandRegex: Regex,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = command( ) = command(
commandRegex, commandRegex,
@@ -132,7 +135,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
subcontextUpdatesFilter = subcontextUpdatesFilter, subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory markerFactory = markerFactory
) { ) {
val args = it.parseCommandsWithParams().let { commandsWithArgs -> val args = it.parseCommandsWithArgs(argsSeparator = argsSeparator).let { commandsWithArgs ->
val key = commandsWithArgs.keys.firstOrNull { it.matches(commandRegex) } ?: return@let null val key = commandsWithArgs.keys.firstOrNull { it.matches(commandRegex) } ?: return@let null
commandsWithArgs[key] commandsWithArgs[key]
} ?: emptyArray() } ?: emptyArray()
@@ -142,51 +145,191 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
suspend fun <BC : BehaviourContext> BC.commandWithArgs( suspend fun <BC : BehaviourContext> BC.commandWithArgs(
command: String, command: String,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = commandWithArgs( ) = commandWithArgs(
command.toRegex(), command.toRegex(),
initialFilter = initialFilter, initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter, subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory, markerFactory = markerFactory,
argsSeparator = argsSeparator,
scenarioReceiver = scenarioReceiver scenarioReceiver = scenarioReceiver
) )
suspend fun <BC : BehaviourContext> BC.commandWithArgs( suspend fun <BC : BehaviourContext> BC.commandWithArgs(
botCommand: BotCommand, botCommand: BotCommand,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = commandWithArgs( ) = commandWithArgs(
botCommand.command, botCommand.command,
initialFilter = initialFilter, initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter, subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory, markerFactory = markerFactory,
argsSeparator = argsSeparator,
scenarioReceiver = scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.commandWithNamedArgs(
commandRegex: Regex,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
) = command(
commandRegex,
requireOnlyCommandInMessage = false,
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory
) {
val args = it.parseCommandsWithNamedArgs(argsSeparator = argsSeparator, nameArgSeparator = nameArgSeparator).let { commandsWithArgs ->
val key = commandsWithArgs.keys.firstOrNull { it.matches(commandRegex) } ?: return@let null
commandsWithArgs[key]
} ?: emptyList()
scenarioReceiver(it, args)
}
suspend fun <BC : BehaviourContext> BC.commandWithNamedArgs(
command: String,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
) = commandWithNamedArgs(
command.toRegex(),
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
nameArgSeparator = nameArgSeparator,
scenarioReceiver = scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.commandWithNamedArgs(
botCommand: BotCommand,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
) = commandWithNamedArgs(
botCommand.command,
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
nameArgSeparator = nameArgSeparator,
scenarioReceiver = scenarioReceiver scenarioReceiver = scenarioReceiver
) )
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs( suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
commandRegex: Regex, commandRegex: Regex,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = commandWithArgs(commandRegex, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = commandWithArgs(
commandRegex = commandRegex,
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
scenarioReceiver = scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs( suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
command: String, command: String,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = onCommandWithArgs(command.toRegex(), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onCommandWithArgs(
commandRegex = command.toRegex(),
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
scenarioReceiver = scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs( suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
botCommand: BotCommand, botCommand: BotCommand,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = onCommandWithArgs(botCommand.command, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onCommandWithArgs(
command = botCommand.command,
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
scenarioReceiver = scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.onCommandWithNamedArgs(
commandRegex: Regex,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
) = commandWithNamedArgs(
commandRegex,
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
nameArgSeparator = nameArgSeparator,
scenarioReceiver = scenarioReceiver,
)
suspend fun <BC : BehaviourContext> BC.onCommandWithNamedArgs(
command: String,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
) = onCommandWithNamedArgs(
command.toRegex(),
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
nameArgSeparator = nameArgSeparator,
scenarioReceiver = scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.onCommandWithNamedArgs(
botCommand: BotCommand,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
) = onCommandWithNamedArgs(
botCommand.command,
initialFilter = initialFilter,
subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory,
argsSeparator = argsSeparator,
nameArgSeparator = nameArgSeparator,
scenarioReceiver = scenarioReceiver
)

View File

@@ -9,7 +9,7 @@ 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.behaviour_builder.utils.times import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextMessage import dev.inmo.tgbotapi.types.message.content.TextMessage
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -20,7 +20,7 @@ import kotlinx.coroutines.Job
suspend fun <BC : BehaviourContext> BC.unhandledCommand( suspend fun <BC : BehaviourContext> BC.unhandledCommand(
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onText( ): Job = onText(
@@ -48,7 +48,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommand(
suspend fun <BC : BehaviourContext> BC.onUnhandledCommand( suspend fun <BC : BehaviourContext> BC.onUnhandledCommand(
requireOnlyCommandInMessage: Boolean = true, requireOnlyCommandInMessage: Boolean = true,
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = unhandledCommand(requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = unhandledCommand(requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@@ -56,7 +56,7 @@ suspend fun <BC : BehaviourContext> BC.onUnhandledCommand(
@PreviewFeature @PreviewFeature
suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs( suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>>
) = onUnhandledCommand( ) = onUnhandledCommand(
@@ -65,7 +65,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs(
subcontextUpdatesFilter = subcontextUpdatesFilter, subcontextUpdatesFilter = subcontextUpdatesFilter,
markerFactory = markerFactory markerFactory = markerFactory
) { ) {
val args = it.parseCommandsWithParams().let { commandsWithArgs -> val args = it.parseCommandsWithArgs().let { commandsWithArgs ->
commandsWithArgs commandsWithArgs
} }
scenarioReceiver(it, args) scenarioReceiver(it, args)
@@ -74,7 +74,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs(
@PreviewFeature @PreviewFeature
suspend fun <BC : BehaviourContext> BC.onUnhandledCommandWithArgs( suspend fun <BC : BehaviourContext> BC.onUnhandledCommandWithArgs(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>>
): Job = unhandledCommandWithArgs(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = unhandledCommandWithArgs(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -46,7 +46,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent>
*/ */
suspend fun <BC : BehaviourContext> BC.onContentMessage( suspend fun <BC : BehaviourContext> BC.onContentMessage(
initialFilter: CommonMessageFilter<MessageContent>? = null, initialFilter: CommonMessageFilter<MessageContent>? = null,
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>>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -70,7 +70,7 @@ suspend fun <BC : BehaviourContext> BC.onContentMessage(
*/ */
suspend fun <BC : BehaviourContext> BC.onContact( suspend fun <BC : BehaviourContext> BC.onContact(
initialFilter: CommonMessageFilter<ContactContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<ContactContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -94,7 +94,7 @@ suspend fun <BC : BehaviourContext> BC.onContact(
*/ */
suspend fun <BC : BehaviourContext> BC.onDice( suspend fun <BC : BehaviourContext> BC.onDice(
initialFilter: CommonMessageFilter<DiceContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<DiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -118,7 +118,7 @@ suspend fun <BC : BehaviourContext> BC.onDice(
*/ */
suspend fun <BC : BehaviourContext> BC.onGame( suspend fun <BC : BehaviourContext> BC.onGame(
initialFilter: CommonMessageFilter<GameContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<GameContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -142,7 +142,7 @@ suspend fun <BC : BehaviourContext> BC.onGame(
*/ */
suspend fun <BC : BehaviourContext> BC.onLocation( suspend fun <BC : BehaviourContext> BC.onLocation(
initialFilter: CommonMessageFilter<LocationContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<LocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -166,7 +166,7 @@ suspend fun <BC : BehaviourContext> BC.onLocation(
*/ */
suspend fun <BC : BehaviourContext> BC.onLiveLocation( suspend fun <BC : BehaviourContext> BC.onLiveLocation(
initialFilter: CommonMessageFilter<LiveLocationContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<LiveLocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LiveLocationMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LiveLocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in LiveLocationMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in LiveLocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LiveLocationMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LiveLocationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -190,7 +190,7 @@ suspend fun <BC : BehaviourContext> BC.onLiveLocation(
*/ */
suspend fun <BC : BehaviourContext> BC.onStaticLocation( suspend fun <BC : BehaviourContext> BC.onStaticLocation(
initialFilter: CommonMessageFilter<StaticLocationContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<StaticLocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StaticLocationMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StaticLocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StaticLocationMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in StaticLocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StaticLocationMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StaticLocationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -214,7 +214,7 @@ suspend fun <BC : BehaviourContext> BC.onStaticLocation(
*/ */
suspend fun <BC : BehaviourContext> BC.onPoll( suspend fun <BC : BehaviourContext> BC.onPoll(
initialFilter: CommonMessageFilter<PollContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<PollContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in PollMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PollMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -238,7 +238,7 @@ suspend fun <BC : BehaviourContext> BC.onPoll(
*/ */
suspend fun <BC : BehaviourContext> BC.onText( suspend fun <BC : BehaviourContext> BC.onText(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -248,6 +248,30 @@ suspend fun <BC : BehaviourContext> BC.onText(
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.onStory(
initialFilter: CommonMessageFilter<StoryContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StoryMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StoryMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StoryMessage>
) = onContentMessageWithType(
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,
@@ -262,7 +286,7 @@ suspend fun <BC : BehaviourContext> BC.onText(
*/ */
suspend fun <BC : BehaviourContext> BC.onTextedContent( suspend fun <BC : BehaviourContext> BC.onTextedContent(
initialFilter: CommonMessageFilter<TextedContent>? = null, initialFilter: CommonMessageFilter<TextedContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextedMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextedMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -286,7 +310,7 @@ suspend fun <BC : BehaviourContext> BC.onTextedContent(
*/ */
suspend fun <BC : BehaviourContext> BC.onVenue( suspend fun <BC : BehaviourContext> BC.onVenue(
initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -310,7 +334,7 @@ suspend fun <BC : BehaviourContext> BC.onVenue(
*/ */
suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup( suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
initialFilter: CommonMessageFilter<AudioMediaGroupPartContent>? = null, initialFilter: CommonMessageFilter<AudioMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -334,7 +358,7 @@ suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
*/ */
suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent( suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
initialFilter: CommonMessageFilter<DocumentMediaGroupPartContent>? = null, initialFilter: CommonMessageFilter<DocumentMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -358,7 +382,7 @@ suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
*/ */
suspend fun <BC : BehaviourContext> BC.onTextedMediaContent( suspend fun <BC : BehaviourContext> BC.onTextedMediaContent(
initialFilter: CommonMessageFilter<TextedMediaContent>? = null, initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -382,7 +406,7 @@ suspend fun <BC : BehaviourContext> BC.onTextedMediaContent(
*/ */
suspend fun <BC : BehaviourContext> BC.onMediaCollection( suspend fun <BC : BehaviourContext> BC.onMediaCollection(
initialFilter: CommonMessageFilter<MediaCollectionContent<TelegramMediaFile>>? = null, initialFilter: CommonMessageFilter<MediaCollectionContent<TelegramMediaFile>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -406,7 +430,7 @@ suspend fun <BC : BehaviourContext> BC.onMediaCollection(
*/ */
suspend fun <BC : BehaviourContext> BC.onMedia( suspend fun <BC : BehaviourContext> BC.onMedia(
initialFilter: CommonMessageFilter<MediaContent>? = null, initialFilter: CommonMessageFilter<MediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -430,7 +454,7 @@ suspend fun <BC : BehaviourContext> BC.onMedia(
*/ */
suspend fun <BC : BehaviourContext> BC.onAnimation( suspend fun <BC : BehaviourContext> BC.onAnimation(
initialFilter: CommonMessageFilter<AnimationContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<AnimationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -454,7 +478,7 @@ suspend fun <BC : BehaviourContext> BC.onAnimation(
*/ */
suspend fun <BC : BehaviourContext> BC.onAudio( suspend fun <BC : BehaviourContext> BC.onAudio(
initialFilter: CommonMessageFilter<AudioContent>? = null, initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -478,7 +502,7 @@ suspend fun <BC : BehaviourContext> BC.onAudio(
*/ */
suspend fun <BC : BehaviourContext> BC.onDocument( suspend fun <BC : BehaviourContext> BC.onDocument(
initialFilter: CommonMessageFilter<DocumentContent>? = null, initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -502,7 +526,7 @@ suspend fun <BC : BehaviourContext> BC.onDocument(
*/ */
suspend fun <BC : BehaviourContext> BC.onPhoto( suspend fun <BC : BehaviourContext> BC.onPhoto(
initialFilter: CommonMessageFilter<PhotoContent>? = null, initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -526,7 +550,7 @@ suspend fun <BC : BehaviourContext> BC.onPhoto(
*/ */
suspend fun <BC : BehaviourContext> BC.onSticker( suspend fun <BC : BehaviourContext> BC.onSticker(
initialFilter: CommonMessageFilter<StickerContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<StickerContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -550,7 +574,7 @@ suspend fun <BC : BehaviourContext> BC.onSticker(
*/ */
suspend fun <BC : BehaviourContext> BC.onVideo( suspend fun <BC : BehaviourContext> BC.onVideo(
initialFilter: CommonMessageFilter<VideoContent>? = null, initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -574,7 +598,7 @@ suspend fun <BC : BehaviourContext> BC.onVideo(
*/ */
suspend fun <BC : BehaviourContext> BC.onVideoNote( suspend fun <BC : BehaviourContext> BC.onVideoNote(
initialFilter: CommonMessageFilter<VideoNoteContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VideoNoteContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -598,7 +622,7 @@ suspend fun <BC : BehaviourContext> BC.onVideoNote(
*/ */
suspend fun <BC : BehaviourContext> BC.onVoice( suspend fun <BC : BehaviourContext> BC.onVoice(
initialFilter: CommonMessageFilter<VoiceContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -622,7 +646,7 @@ suspend fun <BC : BehaviourContext> BC.onVoice(
*/ */
suspend fun <BC : BehaviourContext> BC.onInvoice( suspend fun <BC : BehaviourContext> BC.onInvoice(
initialFilter: CommonMessageFilter<InvoiceContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<InvoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -646,7 +670,7 @@ suspend fun <BC : BehaviourContext> BC.onInvoice(
*/ */
suspend fun <BC : BehaviourContext> BC.onVisualContent( suspend fun <BC : BehaviourContext> BC.onVisualContent(
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null, initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VisualMediaGroupMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VisualMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VisualMediaGroupMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VisualMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VisualMediaGroupMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VisualMediaGroupMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
@@ -670,7 +694,7 @@ suspend fun <BC : BehaviourContext> BC.onVisualContent(
*/ */
suspend fun <BC : BehaviourContext> BC.onMediaContent( suspend fun <BC : BehaviourContext> BC.onMediaContent(
initialFilter: CommonMessageFilter<MediaContent>? = null, initialFilter: CommonMessageFilter<MediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(

View File

@@ -4,27 +4,23 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.* import dev.inmo.micro_utils.coroutines.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitDeepLinks
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory
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.behaviour_builder.utils.times import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextMessage import dev.inmo.tgbotapi.types.message.content.TextMessage
import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import io.ktor.http.decodeURLQueryComponent import io.ktor.http.decodeURLQueryComponent
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.filter
private val startRegex = Regex("start") private val startRegex = Regex("start")
suspend fun <BC : BehaviourContext> BC.onDeepLink( suspend fun <BC : BehaviourContext> BC.onDeepLink(
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null, initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) }, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update>? = { (message, _), update -> MessageFilterByChat(this, message, update) },
markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) }, markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) },
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>>
): Job = on( ): Job = on(
@@ -50,7 +46,7 @@ suspend fun <BC : BehaviourContext> BC.onDeepLink(
suspend fun <BC : BehaviourContext> BC.onDeepLink( suspend fun <BC : BehaviourContext> BC.onDeepLink(
regex: Regex, regex: Regex,
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null, initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) }, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update>? = { (message, _), update -> MessageFilterByChat(this, message, update) },
markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) }, markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) },
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>>
): Job { ): Job {
@@ -63,7 +59,7 @@ suspend fun <BC : BehaviourContext> BC.onDeepLink(
suspend fun <BC : BehaviourContext> BC.onDeepLink( suspend fun <BC : BehaviourContext> BC.onDeepLink(
deepLink: String, deepLink: String,
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null, initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) }, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update>? = { (message, _), update -> MessageFilterByChat(this, message, update) },
markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) }, markerFactory: MarkerFactory<Pair<TextMessage, String>, Any> = MarkerFactory { (message, _) -> ByChatMessageMarkerFactory(message) },
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, Pair<TextMessage, String>>
): Job = onDeepLink(Regex("^$deepLink$"), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onDeepLink(Regex("^$deepLink$"), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -40,7 +40,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent>
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedContentMessage( suspend fun <BC : BehaviourContext> BC.onEditedContentMessage(
initialFilter: CommonMessageFilter<MessageContent>? = null, initialFilter: CommonMessageFilter<MessageContent>? = null,
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>>
)= onEditedContent( )= onEditedContent(
@@ -64,7 +64,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedContentMessage(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedContact( suspend fun <BC : BehaviourContext> BC.onEditedContact(
initialFilter: CommonMessageFilter<ContactContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<ContactContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage>
)= onEditedContent( )= onEditedContent(
@@ -88,7 +88,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedContact(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedDice( suspend fun <BC : BehaviourContext> BC.onEditedDice(
initialFilter: CommonMessageFilter<DiceContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<DiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage>
)= onEditedContent( )= onEditedContent(
@@ -112,7 +112,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedDice(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedGame( suspend fun <BC : BehaviourContext> BC.onEditedGame(
initialFilter: CommonMessageFilter<GameContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<GameContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage>
)= onEditedContent( )= onEditedContent(
@@ -136,7 +136,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedGame(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedLocation( suspend fun <BC : BehaviourContext> BC.onEditedLocation(
initialFilter: CommonMessageFilter<LocationContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<LocationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage>
)= onEditedContent( )= onEditedContent(
@@ -160,7 +160,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedLocation(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedText( suspend fun <BC : BehaviourContext> BC.onEditedText(
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
)= onEditedContent( )= onEditedContent(
@@ -184,7 +184,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedText(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedVenue( suspend fun <BC : BehaviourContext> BC.onEditedVenue(
initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage>
)= onEditedContent( )= onEditedContent(
@@ -208,7 +208,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVenue(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup( suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup(
initialFilter: CommonMessageFilter<AudioMediaGroupPartContent>? = null, initialFilter: CommonMessageFilter<AudioMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage>
)= onEditedContent( )= onEditedContent(
@@ -232,7 +232,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent( suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
initialFilter: CommonMessageFilter<DocumentMediaGroupPartContent>? = null, initialFilter: CommonMessageFilter<DocumentMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage>
)= onEditedContent( )= onEditedContent(
@@ -256,7 +256,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedTextedMediaContent( suspend fun <BC : BehaviourContext> BC.onEditedTextedMediaContent(
initialFilter: CommonMessageFilter<TextedMediaContent>? = null, initialFilter: CommonMessageFilter<TextedMediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage>
)= onEditedContent( )= onEditedContent(
@@ -280,7 +280,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedTextedMediaContent(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedMediaCollection( suspend fun <BC : BehaviourContext> BC.onEditedMediaCollection(
initialFilter: CommonMessageFilter<MediaCollectionContent<TelegramMediaFile>>? = null, initialFilter: CommonMessageFilter<MediaCollectionContent<TelegramMediaFile>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>>
)= onEditedContent( )= onEditedContent(
@@ -304,7 +304,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedMediaCollection(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedMedia( suspend fun <BC : BehaviourContext> BC.onEditedMedia(
initialFilter: CommonMessageFilter<MediaContent>? = null, initialFilter: CommonMessageFilter<MediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
)= onEditedContent( )= onEditedContent(
@@ -328,7 +328,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedMedia(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedAnimation( suspend fun <BC : BehaviourContext> BC.onEditedAnimation(
initialFilter: CommonMessageFilter<AnimationContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<AnimationContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage>
)= onEditedContent( )= onEditedContent(
@@ -352,7 +352,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedAnimation(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedAudio( suspend fun <BC : BehaviourContext> BC.onEditedAudio(
initialFilter: CommonMessageFilter<AudioContent>? = null, initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage>
)= onEditedContent( )= onEditedContent(
@@ -376,7 +376,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedAudio(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedDocument( suspend fun <BC : BehaviourContext> BC.onEditedDocument(
initialFilter: CommonMessageFilter<DocumentContent>? = null, initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage>
)= onEditedContent( )= onEditedContent(
@@ -400,7 +400,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedDocument(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedPhoto( suspend fun <BC : BehaviourContext> BC.onEditedPhoto(
initialFilter: CommonMessageFilter<PhotoContent>? = null, initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage>
)= onEditedContent( )= onEditedContent(
@@ -424,7 +424,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedPhoto(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedSticker( suspend fun <BC : BehaviourContext> BC.onEditedSticker(
initialFilter: CommonMessageFilter<StickerContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<StickerContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage>
)= onEditedContent( )= onEditedContent(
@@ -448,7 +448,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedSticker(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedVideo( suspend fun <BC : BehaviourContext> BC.onEditedVideo(
initialFilter: CommonMessageFilter<VideoContent>? = null, initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage>
)= onEditedContent( )= onEditedContent(
@@ -472,7 +472,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVideo(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedVideoNote( suspend fun <BC : BehaviourContext> BC.onEditedVideoNote(
initialFilter: CommonMessageFilter<VideoNoteContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VideoNoteContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage>
)= onEditedContent( )= onEditedContent(
@@ -496,7 +496,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVideoNote(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedVoice( suspend fun <BC : BehaviourContext> BC.onEditedVoice(
initialFilter: CommonMessageFilter<VoiceContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage>
)= onEditedContent( )= onEditedContent(
@@ -520,7 +520,7 @@ suspend fun <BC : BehaviourContext> BC.onEditedVoice(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedInvoice( suspend fun <BC : BehaviourContext> BC.onEditedInvoice(
initialFilter: CommonMessageFilter<InvoiceContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<InvoiceContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage>
)= onEditedContent( )= onEditedContent(

View File

@@ -655,10 +655,90 @@ suspend fun <BC : BehaviourContext> BC.onGeneralForumTopicUnhidden(
* data * data
*/ */
suspend fun <BC : BehaviourContext> BC.onWriteAccessAllowed( suspend fun <BC : BehaviourContext> BC.onWriteAccessAllowed(
initialFilter: SimpleFilter<SupergroupEventMessage<WriteAccessAllowed>>? = null, initialFilter: SimpleFilter<ChatEventMessage<WriteAccessAllowed>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, SupergroupEventMessage<WriteAccessAllowed>, Update>? = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<WriteAccessAllowed>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<WriteAccessAllowed>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<WriteAccessAllowed>>
) = onEventWithCustomChatEventMessage(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.onWriteAccessAllowedFromRequest(
initialFilter: SimpleFilter<ChatEventMessage<WriteAccessAllowed.FromRequest>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<WriteAccessAllowed.FromRequest>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed.FromRequest>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<WriteAccessAllowed.FromRequest>>
) = onEventWithCustomChatEventMessage(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.onWriteAccessAllowedFromAttachmentMenu(
initialFilter: SimpleFilter<ChatEventMessage<WriteAccessAllowed.FromAttachmentMenu>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<WriteAccessAllowed.FromAttachmentMenu>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed.FromAttachmentMenu>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<WriteAccessAllowed.FromAttachmentMenu>>
) = onEventWithCustomChatEventMessage(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.onWriteAccessAllowedOther(
initialFilter: SimpleFilter<ChatEventMessage<WriteAccessAllowed.Other>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<WriteAccessAllowed.Other>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed.Other>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<WriteAccessAllowed.Other>>
) = onEventWithCustomChatEventMessage(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.onWriteAccessAllowedFromWebAppLink(
initialFilter: SimpleFilter<ChatEventMessage<WriteAccessAllowed.FromWebAppLink>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<WriteAccessAllowed.FromWebAppLink>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed.FromWebAppLink>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<WriteAccessAllowed.FromWebAppLink>>
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -20,7 +20,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : InlineQuery> BC.
/** /**
* @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 **Default is [InlineQueryFilterByUser]]**. 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]. * 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.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
@@ -40,7 +40,7 @@ suspend fun <BC : BehaviourContext> BC.onAnyInlineQuery(
/** /**
* @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 **Default is [InlineQueryFilterByUser]]**. 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]. * 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.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
@@ -60,7 +60,7 @@ suspend fun <BC : BehaviourContext> BC.onBaseInlineQuery(
/** /**
* @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 **Default is [InlineQueryFilterByUser]]**. 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]. * 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.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]

View File

@@ -0,0 +1,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
actual var defaultCoroutineScopeProvider: () -> CoroutineScope = { CoroutineScope(Dispatchers.Default) }

View File

@@ -31,6 +31,8 @@ kotlin {
api libs.microutils.languageCodes api libs.microutils.languageCodes
api libs.ktor.client.core api libs.ktor.client.core
api libs.kslog
} }
} }
commonTest { commonTest {
@@ -55,6 +57,12 @@ kotlin {
} }
} }
linuxArm64Main {
dependencies {
api libs.ktor.client.cio
}
}
mingwX64Main { mingwX64Main {
dependencies { dependencies {
api libs.ktor.client.winhttp api libs.ktor.client.winhttp

View File

@@ -1,10 +1,17 @@
package dev.inmo.tgbotapi.abstracts package dev.inmo.tgbotapi.abstracts
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PreviewChat
/** /**
* All inheritors of this interface have [chat] field and related to this [chat] * All inheritors of this interface have [chat] field and related to this [chat]
*/ */
interface WithChat { interface WithPreviewChat {
val chat: Chat val chat: PreviewChat
} }
/**
* All inheritors of this interface have [chat] field and related to this [chat]
*/
@Deprecated("Renamed", ReplaceWith("WithPreviewChat", "dev.inmo.tgbotapi.abstracts.WithPreviewChat"))
typealias WithChat = WithPreviewChat

View File

@@ -8,7 +8,7 @@ import dev.inmo.tgbotapi.types.chat.User
* *
* @see FromUser * @see FromUser
*/ */
@ClassCastsIncluded @ClassCastsIncluded(excludeRegex = ".*Impl")
interface WithUser { interface WithUser {
val user: User val user: User
} }

View File

@@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.bot.ktor package dev.inmo.tgbotapi.bot.ktor
import dev.inmo.kslog.common.KSLog
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
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.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import io.ktor.client.* import io.ktor.client.*
@@ -14,12 +16,35 @@ import kotlinx.serialization.json.Json
* * On JS, JVM and MingwX64 platforms it is [dev.inmo.tgbotapi.bot.ktor.base.DefaultKtorRequestsExecutor] * * On JS, JVM and MingwX64 platforms it is [dev.inmo.tgbotapi.bot.ktor.base.DefaultKtorRequestsExecutor]
* * On LinuxX64 it is [dev.inmo.tgbotapi.bot.ktor.base.MultipleClientKtorRequestsExecutor] * * On LinuxX64 it is [dev.inmo.tgbotapi.bot.ktor.base.MultipleClientKtorRequestsExecutor]
*/ */
expect class KtorRequestsExecutor ( expect class KtorRequestsExecutor internal constructor(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient,
callsFactories: List<KtorCallFactory>,
excludeDefaultFactories: Boolean,
requestsLimiter: RequestLimiter,
jsonFormatter: Json,
pipelineStepsHolder: KtorPipelineStepsHolder,
logger: KSLog,
diff: Unit // just a diff property to know where constructor and where calling function with defaults
) : BaseRequestsExecutor
fun KtorRequestsExecutor(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper, telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient = HttpClient(), client: HttpClient = HttpClient(),
callsFactories: List<KtorCallFactory> = emptyList(), callsFactories: List<KtorCallFactory> = emptyList(),
excludeDefaultFactories: Boolean = false, excludeDefaultFactories: Boolean = false,
requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter, requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter,
jsonFormatter: Json = nonstrictJsonFormat, jsonFormatter: Json = nonstrictJsonFormat,
pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder,
) : BaseRequestsExecutor logger: KSLog = DefaultKTgBotAPIKSLog,
) = KtorRequestsExecutor(
telegramAPIUrlsKeeper = telegramAPIUrlsKeeper,
client = client,
callsFactories = callsFactories,
excludeDefaultFactories = excludeDefaultFactories,
requestsLimiter = requestsLimiter,
jsonFormatter = jsonFormatter,
pipelineStepsHolder = pipelineStepsHolder,
logger = logger,
diff = kotlin.Unit,
)

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.bot.ktor package dev.inmo.tgbotapi.bot.ktor
import dev.inmo.kslog.common.KSLog
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.bot.ktor.base.* import dev.inmo.tgbotapi.bot.ktor.base.*
@@ -10,9 +11,9 @@ import io.ktor.client.HttpClient
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@RiskFeature @RiskFeature
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf( fun createTelegramBotDefaultKtorCallRequestsFactories(logger: KSLog? = null) = listOf(
SimpleRequestCallFactory(), SimpleRequestCallFactory(logger),
MultipartRequestCallFactory(), MultipartRequestCallFactory(logger),
DownloadFileRequestCallFactory, DownloadFileRequestCallFactory,
DownloadFileChannelRequestCallFactory DownloadFileChannelRequestCallFactory
) )
@@ -25,6 +26,8 @@ class KtorRequestsExecutorBuilder(
var excludeDefaultFactories: Boolean = false var excludeDefaultFactories: Boolean = false
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter
var jsonFormatter: Json = nonstrictJsonFormat var jsonFormatter: Json = nonstrictJsonFormat
var logger: KSLog = DefaultKTgBotAPIKSLog
var pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
fun build() = KtorRequestsExecutor( fun build() = KtorRequestsExecutor(
telegramAPIUrlsKeeper, telegramAPIUrlsKeeper,
@@ -32,7 +35,9 @@ class KtorRequestsExecutorBuilder(
callsFactories, callsFactories,
excludeDefaultFactories, excludeDefaultFactories,
requestsLimiter, requestsLimiter,
jsonFormatter jsonFormatter,
pipelineStepsHolder,
logger
) )
} }

View File

@@ -1,23 +1,30 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.KSLog
import dev.inmo.kslog.common.v
import dev.inmo.kslog.common.w
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.exceptions.newRequestException import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.requests.GetUpdates import dev.inmo.tgbotapi.requests.GetUpdatesRequest
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.Response import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.plugins.timeout import io.ktor.client.plugins.timeout
import io.ktor.client.request.* import io.ktor.client.request.*
import io.ktor.client.statement.bodyAsText import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType import io.ktor.http.ContentType
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlin.collections.set import kotlin.collections.set
var defaultUpdateTimeoutForZeroDelay = 1000L var defaultUpdateTimeoutForZeroDelay = 1000L
abstract class AbstractRequestCallFactory : KtorCallFactory { abstract class AbstractRequestCallFactory(
protected open val logger: KSLog = DefaultKTgBotAPIKSLog
) : KtorCallFactory {
private val methodsCache: MutableMap<String, String> = mutableMapOf() private val methodsCache: MutableMap<String, String> = mutableMapOf()
override suspend fun <T : Any> makeCall( override suspend fun <T : Any> makeCall(
client: HttpClient, client: HttpClient,
@@ -26,6 +33,7 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
jsonFormatter: Json jsonFormatter: Json
): T? { ): T? {
val preparedBody = prepareCallBody(client, urlsKeeper, request) ?: return null val preparedBody = prepareCallBody(client, urlsKeeper, request) ?: return null
logger.v { "Prepared body for $request: $preparedBody" }
client.post { client.post {
url( url(
@@ -35,7 +43,7 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
) )
accept(ContentType.Application.Json) accept(ContentType.Application.Json)
if (request is GetUpdates) { if (request is GetUpdatesRequest) {
request.timeout?.times(1000L) ?.let { customTimeoutMillis -> request.timeout?.times(1000L) ?.let { customTimeoutMillis ->
if (customTimeoutMillis > 0) { if (customTimeoutMillis > 0) {
timeout { timeout {
@@ -54,7 +62,9 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
setBody(preparedBody) setBody(preparedBody)
}.let { response -> }.let { response ->
val content = response.bodyAsText() val content = response.bodyAsText()
logger.v { "Raw answer for $request: $content" }
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
logger.v { "Answer as json for $request: $responseObject" }
return runCatchingSafely { return runCatchingSafely {
(responseObject.result?.let { (responseObject.result?.let {
@@ -66,6 +76,8 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
"Can't get result object from $content" "Can't get result object from $content"
) )
}) })
}.onFailure {
logger.w { "Got exception answer for $request: $it" }
}.getOrThrow() }.getOrThrow()
} }
} }

View File

@@ -1,12 +1,16 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.*
import dev.inmo.micro_utils.coroutines.defaultSafelyExceptionHandler
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.exceptions.BotException import dev.inmo.tgbotapi.bot.exceptions.BotException
import dev.inmo.tgbotapi.bot.exceptions.CommonBotException import dev.inmo.tgbotapi.bot.exceptions.CommonBotException
import dev.inmo.tgbotapi.bot.exceptions.GetUpdatesConflict
import dev.inmo.tgbotapi.bot.exceptions.newRequestException import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutor
import dev.inmo.tgbotapi.bot.ktor.createTelegramBotDefaultKtorCallRequestsFactories import dev.inmo.tgbotapi.bot.ktor.createTelegramBotDefaultKtorCallRequestsFactories
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
@@ -19,19 +23,23 @@ import io.ktor.client.plugins.*
import io.ktor.client.statement.* import io.ktor.client.statement.*
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
class DefaultKtorRequestsExecutor( class DefaultKtorRequestsExecutor internal constructor(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper, telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient = HttpClient(), client: HttpClient,
callsFactories: List<KtorCallFactory> = emptyList(), callsFactories: List<KtorCallFactory>,
excludeDefaultFactories: Boolean = false, excludeDefaultFactories: Boolean,
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter, private val requestsLimiter: RequestLimiter,
private val jsonFormatter: Json = nonstrictJsonFormat, private val jsonFormatter: Json,
private val pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder private val pipelineStepsHolder: KtorPipelineStepsHolder,
private val logger: KSLog,
diff: Unit
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) { ) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
private val callsFactories: List<KtorCallFactory> = callsFactories.run { private val callsFactories: List<KtorCallFactory> = callsFactories.run {
if (!excludeDefaultFactories) { if (!excludeDefaultFactories) {
this + createTelegramBotDefaultKtorCallRequestsFactories() logger.v { "Installing default factories" }
this + createTelegramBotDefaultKtorCallRequestsFactories(logger)
} else { } else {
logger.v { "Default factories will not be installed" }
this this
} }
} }
@@ -44,19 +52,23 @@ class DefaultKtorRequestsExecutor(
override suspend fun <T : Any> execute(request: Request<T>): T { override suspend fun <T : Any> execute(request: Request<T>): T {
return runCatchingSafely { return runCatchingSafely {
logger.v { "Start request $request" }
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
requestsLimiter.limit(request) { requestsLimiter.limit(request) {
var result: T? = null var result: T? = null
lateinit var factoryHandledRequest: KtorCallFactory lateinit var factoryHandledRequest: KtorCallFactory
for (potentialFactory in callsFactories) { for (potentialFactory in callsFactories) {
pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory) pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory)
result = potentialFactory.makeCall( logger.v { "Trying factory $potentialFactory for $request" }
val resultFromFactory = potentialFactory.makeCall(
client, client,
telegramAPIUrlsKeeper, telegramAPIUrlsKeeper,
request, request,
jsonFormatter jsonFormatter
) )
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory) logger.v { "Result of factory $potentialFactory handling $request: $resultFromFactory" }
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(resultFromFactory, request, potentialFactory)
logger.v { "Result of pipeline $pipelineStepsHolder handling $resultFromFactory: $result" }
if (result != null) { if (result != null) {
factoryHandledRequest = potentialFactory factoryHandledRequest = potentialFactory
break break
@@ -69,6 +81,7 @@ class DefaultKtorRequestsExecutor(
} }
}.let { }.let {
val result = it.exceptionOrNull() ?.let { e -> val result = it.exceptionOrNull() ?.let { e ->
logger.v(e) { "Got exception on handling of $request" }
pipelineStepsHolder.onRequestException(request, e) ?.let { return@let it } pipelineStepsHolder.onRequestException(request, e) ?.let { return@let it }
when (e) { when (e) {
@@ -88,9 +101,18 @@ class DefaultKtorRequestsExecutor(
} }
is BotException -> e is BotException -> e
else -> CommonBotException(cause = e) else -> CommonBotException(cause = e)
}.also { newException ->
logger.v(newException) { "Result exception on handling of $request is an exception" }
if (newException is GetUpdatesConflict) {
logger.w(newException) {
"Warning!!! Other bot with the same bot token requests updates with getUpdate in parallel"
}
}
} }
} ?.let { Result.failure(it) } ?: it } ?.let { Result.failure(it) } ?: it
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories) pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories).also {
logger.v { "Result of handling $request: $it" }
}
} }
} }

View File

@@ -5,6 +5,7 @@ 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
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.call.receive import io.ktor.client.call.receive
@@ -15,6 +16,7 @@ import io.ktor.utils.io.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@RiskFeature
object DownloadFileChannelRequestCallFactory : KtorCallFactory { object DownloadFileChannelRequestCallFactory : KtorCallFactory {
override suspend fun <T : Any> makeCall( override suspend fun <T : Any> makeCall(
client: HttpClient, client: HttpClient,

View File

@@ -4,12 +4,14 @@ import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.requests.DownloadFile import dev.inmo.tgbotapi.requests.DownloadFile
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.statement.readBytes import io.ktor.client.statement.readBytes
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@RiskFeature
object DownloadFileRequestCallFactory : KtorCallFactory { object DownloadFileRequestCallFactory : KtorCallFactory {
override suspend fun <T : Any> makeCall( override suspend fun <T : Any> makeCall(
client: HttpClient, client: HttpClient,

View File

@@ -1,6 +1,8 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.KSLog
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import dev.inmo.tgbotapi.utils.mapWithCommonValues import dev.inmo.tgbotapi.utils.mapWithCommonValues
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
@@ -8,7 +10,7 @@ import io.ktor.client.request.forms.*
import io.ktor.http.Headers import io.ktor.http.Headers
import io.ktor.http.HttpHeaders import io.ktor.http.HttpHeaders
class MultipartRequestCallFactory : AbstractRequestCallFactory() { class MultipartRequestCallFactory(logger: KSLog? = null) : AbstractRequestCallFactory(logger ?: DefaultKTgBotAPIKSLog) {
override fun <T : Any> prepareCallBody( override fun <T : Any> prepareCallBody(
client: HttpClient, client: HttpClient,
urlsKeeper: TelegramAPIUrlsKeeper, urlsKeeper: TelegramAPIUrlsKeeper,

View File

@@ -1,12 +1,16 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutor
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
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import io.ktor.client.* import io.ktor.client.*
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
@@ -45,6 +49,7 @@ class MultipleClientKtorRequestsExecutor (
jsonFormatter: Json, jsonFormatter: Json,
pipelineStepsHolder: KtorPipelineStepsHolder, pipelineStepsHolder: KtorPipelineStepsHolder,
requestExecutorsCount: Int, requestExecutorsCount: Int,
logger: KSLog,
clientFactory: () -> HttpClient clientFactory: () -> HttpClient
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) { ) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
private val requestExecutors = (0 until requestExecutorsCount).map { private val requestExecutors = (0 until requestExecutorsCount).map {
@@ -55,7 +60,9 @@ class MultipleClientKtorRequestsExecutor (
excludeDefaultFactories, excludeDefaultFactories,
requestsLimiter, requestsLimiter,
jsonFormatter, jsonFormatter,
pipelineStepsHolder pipelineStepsHolder,
logger,
Unit
) )
}.toSet() }.toSet()
private val freeClients = MutableStateFlow<Set<DefaultKtorRequestsExecutor>>(requestExecutors) private val freeClients = MutableStateFlow<Set<DefaultKtorRequestsExecutor>>(requestExecutors)
@@ -68,14 +75,16 @@ class MultipleClientKtorRequestsExecutor (
} }
} }
constructor( internal constructor(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper, telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient, client: HttpClient,
callsFactories: List<KtorCallFactory>, callsFactories: List<KtorCallFactory>,
excludeDefaultFactories: Boolean, excludeDefaultFactories: Boolean,
requestsLimiter: RequestLimiter, requestsLimiter: RequestLimiter,
jsonFormatter: Json, jsonFormatter: Json,
pipelineStepsHolder: KtorPipelineStepsHolder pipelineStepsHolder: KtorPipelineStepsHolder,
logger: KSLog,
diff: Unit
) : this( ) : this(
telegramAPIUrlsKeeper, telegramAPIUrlsKeeper,
callsFactories, callsFactories,
@@ -84,6 +93,7 @@ class MultipleClientKtorRequestsExecutor (
jsonFormatter, jsonFormatter,
pipelineStepsHolder, pipelineStepsHolder,
client.engineConfig.threadsCount, client.engineConfig.threadsCount,
logger,
{ platformClientCopy(client) } { platformClientCopy(client) }
) )

View File

@@ -1,12 +1,14 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.KSLog
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.http.ContentType import io.ktor.http.ContentType
import io.ktor.http.content.TextContent import io.ktor.http.content.TextContent
class SimpleRequestCallFactory : AbstractRequestCallFactory() { class SimpleRequestCallFactory(logger: KSLog? = null) : AbstractRequestCallFactory(logger ?: DefaultKTgBotAPIKSLog) {
override fun <T : Any> prepareCallBody( override fun <T : Any> prepareCallBody(
client: HttpClient, client: HttpClient,
urlsKeeper: TelegramAPIUrlsKeeper, urlsKeeper: TelegramAPIUrlsKeeper,

View File

@@ -22,13 +22,11 @@ private val updatesListSerializer = ListSerializer(
*/ */
@Serializable @Serializable
data class GetUpdates( data class GetUpdates(
val offset: UpdateIdentifier? = null,// set `last update id + 1` to receive next part of updates override val offset: UpdateIdentifier? = null,// set `last update id + 1` to receive next part of updates
val limit: Int = getUpdatesLimit.last, override val limit: Int = getUpdatesLimit.last,
val timeout: Seconds? = null, override val timeout: Seconds? = null,
val allowed_updates: List<String>? = ALL_UPDATES_LIST override val allowed_updates: List<String>? = ALL_UPDATES_LIST
): SimpleRequest<List<Update>> { ): GetUpdatesRequest<List<Update>> {
override fun method(): String = "getUpdates"
override val resultDeserializer: DeserializationStrategy<List<Update>> override val resultDeserializer: DeserializationStrategy<List<Update>>
get() = updatesListSerializer get() = updatesListSerializer

View File

@@ -0,0 +1,37 @@
package dev.inmo.tgbotapi.requests
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ALL_UPDATES_LIST
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.getUpdatesLimit
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.json.JsonArray
/**
* Raw variant of [GetUpdates]. This type will be useful in case you wish to get some updates and handle them by
* yourself or with [dev.inmo.tgbotapi.utils.convertWithMediaGroupUpdates]
*/
@Serializable
data class GetUpdatesRaw(
override val offset: UpdateIdentifier? = null,// set `last update id + 1` to receive next part of updates
override val limit: Int = getUpdatesLimit.last,
override val timeout: Seconds? = null,
override val allowed_updates: List<String>? = ALL_UPDATES_LIST
): GetUpdatesRequest<JsonArray> {
override fun method(): String = "getUpdates"
override val resultDeserializer: DeserializationStrategy<JsonArray>
get() = JsonArray.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
init {
if (limit !in getUpdatesLimit) {
error("GetUpdates request can be called only with limit in range $getUpdatesLimit (actual value is $limit)")
}
}
}

View File

@@ -0,0 +1,17 @@
package dev.inmo.tgbotapi.requests
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ALL_UPDATES_LIST
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.getUpdatesLimit
interface GetUpdatesRequest<T : Any> : SimpleRequest<T> {
val offset: UpdateIdentifier?
val limit: Int
val timeout: Seconds?
val allowed_updates: List<String>?
override fun method(): String = "getUpdates"
}

View File

@@ -2,14 +2,14 @@ package dev.inmo.tgbotapi.requests.bot
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRightsImpl import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
@Serializable @Serializable
class SetMyDefaultAdministratorRights( class SetMyDefaultAdministratorRights(
@SerialName(rightsField) @SerialName(rightsField)
val rights: ChatAdministratorRightsImpl, val rights: ChatCommonAdministratorRights,
@SerialName(forChannelsField) @SerialName(forChannelsField)
val forChannels: Boolean? = null val forChannels: Boolean? = null
) : SimpleRequest<Boolean> { ) : SimpleRequest<Boolean> {

View File

@@ -0,0 +1,14 @@
package dev.inmo.tgbotapi.requests.chat.forum
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
@Serializable
data class UnpinAllGeneralForumTopicMessages (
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
): ModifyForumRequest {
override fun method(): String = "unpinAllGeneralForumTopicMessages"
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.members package dev.inmo.tgbotapi.requests.chat.members
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.abstracts.types.UntilDate import dev.inmo.tgbotapi.abstracts.types.UntilDate
import dev.inmo.tgbotapi.requests.chat.abstracts.ChatMemberRequest import dev.inmo.tgbotapi.requests.chat.abstracts.ChatMemberRequest
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -7,6 +8,7 @@ import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
@Serializable @Serializable
@Warning("This method is too common. Use it with caution")
data class PromoteChatMember( data class PromoteChatMember(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@@ -37,7 +39,13 @@ data class PromoteChatMember(
@SerialName(canManageChatField) @SerialName(canManageChatField)
private val canManageChat: Boolean? = null, private val canManageChat: Boolean? = null,
@SerialName(canManageTopicsField) @SerialName(canManageTopicsField)
private val canManageTopics: Boolean? = null private val canManageTopics: Boolean? = null,
@SerialName(canPostStoriesField)
private val canPostStories: Boolean? = null,
@SerialName(canEditStoriesField)
private val canEditStories: Boolean? = null,
@SerialName(canDeleteStoriesField)
private val canDeleteStories: Boolean? = null
) : ChatMemberRequest<Boolean>, UntilDate { ) : ChatMemberRequest<Boolean>, UntilDate {
override fun method(): String = "promoteChatMember" override fun method(): String = "promoteChatMember"
override val resultDeserializer: DeserializationStrategy<Boolean> override val resultDeserializer: DeserializationStrategy<Boolean>
@@ -45,3 +53,109 @@ data class PromoteChatMember(
override val requestSerializer: SerializationStrategy<*> override val requestSerializer: SerializationStrategy<*>
get() = serializer() get() = serializer()
} }
fun PromoteChatMember(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
) = PromoteChatMember(
chatId = chatId,
userId = userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = null,
canEditMessages = null,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = null,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = null,
canPostStories = null,
canEditStories = null,
canDeleteStories = null
)
fun PromoteChannelAdministrator(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canPostMessages: Boolean? = null,
canEditMessages: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canPostStories: Boolean? = null,
canEditStories: Boolean? = null,
canDeleteStories: Boolean? = null
) = PromoteChatMember(
chatId = chatId,
userId = userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = canPostMessages,
canEditMessages = canEditMessages,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = null,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = null,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
)
fun PromoteSupergroupAdministrator(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null,
isAnonymous: Boolean? = null,
canChangeInfo: Boolean? = null,
canDeleteMessages: Boolean? = null,
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null,
canManageVideoChats: Boolean? = null,
canManageChat: Boolean? = null,
canManageTopics: Boolean? = null,
) = PromoteChatMember(
chatId = chatId,
userId = userId,
untilDate = untilDate,
isAnonymous = isAnonymous,
canChangeInfo = canChangeInfo,
canPostMessages = null,
canEditMessages = null,
canDeleteMessages = canDeleteMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = canPinMessages,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
canManageTopics = canManageTopics,
canPostStories = null,
canEditStories = null,
canDeleteStories = null
)

View File

@@ -177,6 +177,11 @@ val stickerKeywordLengthLimit = 0 .. 64
const val botActionActualityTime: Seconds = 5 const val botActionActualityTime: Seconds = 5
val cloudStorageKeyLimit = 1 .. 128
val cloudStorageValueLimit = 0 .. 4096
val cloudStorageKeyRegex = Regex("[A-Za-z0-9_-]{${cloudStorageKeyLimit.first},${cloudStorageKeyLimit.last}}")
val cloudStorageValueRegex = Regex(".{${cloudStorageValueLimit.first},${cloudStorageValueLimit.last}}")
// Made as lazy for correct work in K/JS // Made as lazy for correct work in K/JS
val telegramInlineModeGifPermittedMimeTypes by lazy { val telegramInlineModeGifPermittedMimeTypes by lazy {
listOf( listOf(
@@ -210,10 +215,12 @@ const val firstNameField = "first_name"
const val lastNameField = "last_name" const val lastNameField = "last_name"
const val languageCodeField = "language_code" const val languageCodeField = "language_code"
const val addedToAttachmentMenuField = "added_to_attachment_menu" const val addedToAttachmentMenuField = "added_to_attachment_menu"
const val allowsWriteToPMField = "allows_write_to_pm"
const val isPremiumField = "is_premium" const val isPremiumField = "is_premium"
const val hasPrivateForwardsField = "has_private_forwards" const val hasPrivateForwardsField = "has_private_forwards"
const val hasRestrictedVoiceAndVideoMessagesField = "has_restricted_voice_and_video_messages" const val hasRestrictedVoiceAndVideoMessagesField = "has_restricted_voice_and_video_messages"
const val emojiStatusCustomEmojiIdField = "emoji_status_custom_emoji_id" const val emojiStatusCustomEmojiIdField = "emoji_status_custom_emoji_id"
const val emojiStatusExpirationDateField = "emoji_status_expiration_date"
const val iconCustomEmojiIdField = "icon_custom_emoji_id" const val iconCustomEmojiIdField = "icon_custom_emoji_id"
const val canJoinGroupsField = "can_join_groups" const val canJoinGroupsField = "can_join_groups"
const val canReadAllGroupMessagesField = "can_read_all_group_messages" const val canReadAllGroupMessagesField = "can_read_all_group_messages"
@@ -273,6 +280,9 @@ const val correctOptionIdField = "correct_option_id"
const val allowsMultipleAnswersField = "allows_multiple_answers" const val allowsMultipleAnswersField = "allows_multiple_answers"
const val isAnonymousField = "is_anonymous" const val isAnonymousField = "is_anonymous"
const val canManageTopicsField = "can_manage_topics" const val canManageTopicsField = "can_manage_topics"
const val canPostStoriesField = "can_post_stories"
const val canEditStoriesField = "can_edit_stories"
const val canDeleteStoriesField = "can_delete_stories"
const val captionEntitiesField = "caption_entities" const val captionEntitiesField = "caption_entities"
const val hasSpoilerField = "has_spoiler" const val hasSpoilerField = "has_spoiler"
const val loginUrlField = "login_url" const val loginUrlField = "login_url"
@@ -289,6 +299,7 @@ const val pinnedMessageField = "pinned_message"
const val activeUsernamesField = "active_usernames" const val activeUsernamesField = "active_usernames"
const val customTitleField = "custom_title" const val customTitleField = "custom_title"
const val optionIdsField = "option_ids" const val optionIdsField = "option_ids"
const val voterChatField = "voter_chat"
const val ipAddressField = "ip_address" const val ipAddressField = "ip_address"
const val linkedChatIdField = "linked_chat_id" const val linkedChatIdField = "linked_chat_id"
const val hasHiddenMembersField = "has_hidden_members" const val hasHiddenMembersField = "has_hidden_members"

View File

@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable(InlineQueryResultSerializer::class) @Serializable(InlineQueryResultSerializer::class)
@ClassCastsIncluded @ClassCastsIncluded(excludeRegex = ".*Impl")
interface InlineQueryResult { interface InlineQueryResult {
val type: String val type: String
val id: InlineQueryIdentifier val id: InlineQueryIdentifier

View File

@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.buttons
import dev.inmo.tgbotapi.types.botAdministratorRightsField import dev.inmo.tgbotapi.types.botAdministratorRightsField
import dev.inmo.tgbotapi.types.botIsMemberField import dev.inmo.tgbotapi.types.botIsMemberField
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRights import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights
import dev.inmo.tgbotapi.types.chatHasUsernameField import dev.inmo.tgbotapi.types.chatHasUsernameField
import dev.inmo.tgbotapi.types.chatIsChannelField import dev.inmo.tgbotapi.types.chatIsChannelField
import dev.inmo.tgbotapi.types.chatIsCreatedField import dev.inmo.tgbotapi.types.chatIsCreatedField
@@ -30,9 +30,9 @@ data class KeyboardButtonRequestChat(
@SerialName(chatIsCreatedField) @SerialName(chatIsCreatedField)
val isOwnedBy: Boolean? = null, val isOwnedBy: Boolean? = null,
@SerialName(userAdministratorRightsField) @SerialName(userAdministratorRightsField)
val userRightsInChat: ChatAdministratorRights? = null, val userRightsInChat: ChatCommonAdministratorRights? = null,
@SerialName(botAdministratorRightsField) @SerialName(botAdministratorRightsField)
val botRightsInChat: ChatAdministratorRights? = null, val botRightsInChat: ChatCommonAdministratorRights? = null,
@SerialName(botIsMemberField) @SerialName(botIsMemberField)
val botIsMember: Boolean? = null val botIsMember: Boolean? = null
) { ) {
@@ -41,8 +41,8 @@ data class KeyboardButtonRequestChat(
requestId: RequestId, requestId: RequestId,
isPublic: Boolean? = null, isPublic: Boolean? = null,
isOwnedBy: Boolean? = null, isOwnedBy: Boolean? = null,
userRightsInChat: ChatAdministratorRights? = null, userRightsInChat: ChatCommonAdministratorRights? = null,
botRightsInChat: ChatAdministratorRights? = null, botRightsInChat: ChatCommonAdministratorRights? = null,
botIsMember: Boolean? = null botIsMember: Boolean? = null
) = KeyboardButtonRequestChat( ) = KeyboardButtonRequestChat(
requestId = requestId, requestId = requestId,
@@ -60,8 +60,8 @@ data class KeyboardButtonRequestChat(
isForum: Boolean? = null, isForum: Boolean? = null,
isPublic: Boolean? = null, isPublic: Boolean? = null,
isOwnedBy: Boolean? = null, isOwnedBy: Boolean? = null,
userRightsInChat: ChatAdministratorRights? = null, userRightsInChat: ChatCommonAdministratorRights? = null,
botRightsInChat: ChatAdministratorRights? = null, botRightsInChat: ChatCommonAdministratorRights? = null,
botIsMember: Boolean? = null botIsMember: Boolean? = null
) = KeyboardButtonRequestChat( ) = KeyboardButtonRequestChat(
requestId = requestId, requestId = requestId,

View File

@@ -5,20 +5,14 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.*
import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.types.webapps.WebAppInfo
/** /**
* Creates and put [PayInlineKeyboardButton] * Creates [PayInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun payInlineButton( inline fun payInlineButton(
text: String text: String
) = PayInlineKeyboardButton(text) ) = PayInlineKeyboardButton(text)
/** /**
* Creates and put [CallbackDataInlineKeyboardButton] * Creates [CallbackDataInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun dataInlineButton( inline fun dataInlineButton(
text: String, text: String,
@@ -26,20 +20,14 @@ inline fun dataInlineButton(
) = CallbackDataInlineKeyboardButton(text, data) ) = CallbackDataInlineKeyboardButton(text, data)
/** /**
* Creates and put [CallbackGameInlineKeyboardButton] * Creates [CallbackGameInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun gameInlineButton( inline fun gameInlineButton(
text: String text: String
) = CallbackGameInlineKeyboardButton(text) ) = CallbackGameInlineKeyboardButton(text)
/** /**
* Creates and put [LoginURLInlineKeyboardButton] * Creates [LoginURLInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun loginInlineButton( inline fun loginInlineButton(
text: String, text: String,
@@ -47,10 +35,7 @@ inline fun loginInlineButton(
) = LoginURLInlineKeyboardButton(text, loginUrl) ) = LoginURLInlineKeyboardButton(text, loginUrl)
/** /**
* Creates and put [SwitchInlineQueryCurrentChatInlineKeyboardButton] * Creates [SwitchInlineQueryCurrentChatInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun inlineQueryInCurrentChatInlineButton( inline fun inlineQueryInCurrentChatInlineButton(
text: String, text: String,
@@ -58,10 +43,7 @@ inline fun inlineQueryInCurrentChatInlineButton(
) = SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data) ) = SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data)
/** /**
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton] * Creates [SwitchInlineQueryChosenChatInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun inlineQueryInCurrentChatInlineButton( inline fun inlineQueryInCurrentChatInlineButton(
text: String, text: String,
@@ -69,10 +51,7 @@ inline fun inlineQueryInCurrentChatInlineButton(
) = SwitchInlineQueryChosenChatInlineKeyboardButton(text, parameters) ) = SwitchInlineQueryChosenChatInlineKeyboardButton(text, parameters)
/** /**
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton] * Creates [SwitchInlineQueryChosenChatInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun inlineQueryInCurrentChatInlineButton( inline fun inlineQueryInCurrentChatInlineButton(
text: String, text: String,
@@ -93,10 +72,7 @@ inline fun inlineQueryInCurrentChatInlineButton(
) )
/** /**
* Creates and put [SwitchInlineQueryChosenChatInlineKeyboardButton] * Creates [SwitchInlineQueryChosenChatInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun inlineQueryInAnyCurrentChatInlineButton( inline fun inlineQueryInAnyCurrentChatInlineButton(
text: String, text: String,
@@ -104,10 +80,7 @@ inline fun inlineQueryInAnyCurrentChatInlineButton(
) = inlineQueryInCurrentChatInlineButton(text, query, allowUsers = true, allowBots = true, allowGroups = true, allowChannels = true) ) = inlineQueryInCurrentChatInlineButton(text, query, allowUsers = true, allowBots = true, allowGroups = true, allowChannels = true)
/** /**
* Creates and put [SwitchInlineQueryInlineKeyboardButton] * Creates [SwitchInlineQueryInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun inlineQueryInlineButton( inline fun inlineQueryInlineButton(
text: String, text: String,
@@ -115,10 +88,7 @@ inline fun inlineQueryInlineButton(
) = SwitchInlineQueryInlineKeyboardButton(text, data) ) = SwitchInlineQueryInlineKeyboardButton(text, data)
/** /**
* Creates and put [URLInlineKeyboardButton] * Creates [URLInlineKeyboardButton]
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun urlInlineButton( inline fun urlInlineButton(
text: String, text: String,
@@ -126,10 +96,7 @@ inline fun urlInlineButton(
) = URLInlineKeyboardButton(text, url) ) = URLInlineKeyboardButton(text, url)
/** /**
* Creates and put [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only * Creates [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun webAppInlineButton( inline fun webAppInlineButton(
text: String, text: String,
@@ -137,10 +104,7 @@ inline fun webAppInlineButton(
) = WebAppInlineKeyboardButton(text, webApp) ) = WebAppInlineKeyboardButton(text, webApp)
/** /**
* Creates and put [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only * Creates [WebAppInlineKeyboardButton]. Please, remember that this button is available in private chats only
*
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/ */
inline fun webAppInlineButton( inline fun webAppInlineButton(
text: String, text: String,

View File

@@ -1,47 +1,34 @@
package dev.inmo.tgbotapi.types.buttons.reply package dev.inmo.tgbotapi.types.buttons.reply
import dev.inmo.tgbotapi.types.buttons.* import dev.inmo.tgbotapi.types.buttons.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.* import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRights
import dev.inmo.tgbotapi.types.request.RequestId import dev.inmo.tgbotapi.types.request.RequestId
import dev.inmo.tgbotapi.types.webapps.WebAppInfo import dev.inmo.tgbotapi.types.webapps.WebAppInfo
/** /**
* Creates and put [SimpleKeyboardButton] * Creates [SimpleKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun simpleReplyButton( inline fun simpleReplyButton(
text: String text: String
) = SimpleKeyboardButton(text) ) = SimpleKeyboardButton(text)
/** /**
* Creates and put [RequestContactKeyboardButton] * Creates [RequestContactKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestContactReplyButton( inline fun requestContactReplyButton(
text: String text: String
) = RequestContactKeyboardButton(text) ) = RequestContactKeyboardButton(text)
/** /**
* Creates and put [RequestLocationKeyboardButton] * Creates [RequestLocationKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestLocationReplyButton( inline fun requestLocationReplyButton(
text: String text: String
) = RequestLocationKeyboardButton(text) ) = RequestLocationKeyboardButton(text)
/** /**
* Creates and put [RequestPollKeyboardButton] * Creates [RequestPollKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestPollReplyButton( inline fun requestPollReplyButton(
text: String, text: String,
@@ -49,10 +36,7 @@ inline fun requestPollReplyButton(
) = RequestPollKeyboardButton(text, pollType) ) = RequestPollKeyboardButton(text, pollType)
/** /**
* Creates and put [WebAppKeyboardButton] * Creates [WebAppKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun webAppReplyButton( inline fun webAppReplyButton(
text: String, text: String,
@@ -60,10 +44,7 @@ inline fun webAppReplyButton(
) = WebAppKeyboardButton(text, webApp) ) = WebAppKeyboardButton(text, webApp)
/** /**
* Creates and put [WebAppKeyboardButton] * Creates [WebAppKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun webAppReplyButton( inline fun webAppReplyButton(
text: String, text: String,
@@ -72,10 +53,7 @@ inline fun webAppReplyButton(
/** /**
* Creates and put [RequestUserKeyboardButton] * Creates [RequestUserKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestUserReplyButton( inline fun requestUserReplyButton(
text: String, text: String,
@@ -86,10 +64,7 @@ inline fun requestUserReplyButton(
) )
/** /**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Bot] * Creates [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Bot]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestBotReplyButton( inline fun requestBotReplyButton(
text: String, text: String,
@@ -100,10 +75,7 @@ inline fun requestBotReplyButton(
) )
/** /**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Common] * Creates [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Common]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestUserReplyButton( inline fun requestUserReplyButton(
text: String, text: String,
@@ -115,10 +87,7 @@ inline fun requestUserReplyButton(
) )
/** /**
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Any] * Creates [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Any]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestUserOrBotReplyButton( inline fun requestUserOrBotReplyButton(
text: String, text: String,
@@ -130,10 +99,7 @@ inline fun requestUserOrBotReplyButton(
/** /**
* Creates and put [RequestChatKeyboardButton] * Creates [RequestChatKeyboardButton]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestChatReplyButton( inline fun requestChatReplyButton(
text: String, text: String,
@@ -144,10 +110,7 @@ inline fun requestChatReplyButton(
) )
/** /**
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat] * Creates [RequestChatKeyboardButton] with [KeyboardButtonRequestChat]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestChatReplyButton( inline fun requestChatReplyButton(
text: String, text: String,
@@ -156,8 +119,8 @@ inline fun requestChatReplyButton(
isForum: Boolean? = null, isForum: Boolean? = null,
isPublic: Boolean? = null, isPublic: Boolean? = null,
isOwnedBy: Boolean? = null, isOwnedBy: Boolean? = null,
userRightsInChat: ChatAdministratorRights? = null, userRightsInChat: ChatCommonAdministratorRights? = null,
botRightsInChat: ChatAdministratorRights? = null, botRightsInChat: ChatCommonAdministratorRights? = null,
botIsMember: Boolean = false botIsMember: Boolean = false
) = requestChatReplyButton( ) = requestChatReplyButton(
text, text,
@@ -174,18 +137,15 @@ inline fun requestChatReplyButton(
) )
/** /**
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Channel] * Creates [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Channel]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestChannelReplyButton( inline fun requestChannelReplyButton(
text: String, text: String,
requestId: RequestId, requestId: RequestId,
isPublic: Boolean? = null, isPublic: Boolean? = null,
isOwnedBy: Boolean? = null, isOwnedBy: Boolean? = null,
userRightsInChat: ChatAdministratorRights? = null, userRightsInChat: ChatCommonAdministratorRights? = null,
botRightsInChat: ChatAdministratorRights? = null, botRightsInChat: ChatCommonAdministratorRights? = null,
botIsMember: Boolean = false botIsMember: Boolean = false
) = requestChatReplyButton( ) = requestChatReplyButton(
text, text,
@@ -201,10 +161,7 @@ inline fun requestChannelReplyButton(
/** /**
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Group] * Creates [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Group]
*
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/ */
inline fun requestChannelReplyButton( inline fun requestChannelReplyButton(
text: String, text: String,
@@ -212,8 +169,8 @@ inline fun requestChannelReplyButton(
isForum: Boolean? = null, isForum: Boolean? = null,
isPublic: Boolean? = null, isPublic: Boolean? = null,
isOwnedBy: Boolean? = null, isOwnedBy: Boolean? = null,
userRightsInChat: ChatAdministratorRights? = null, userRightsInChat: ChatCommonAdministratorRights? = null,
botRightsInChat: ChatAdministratorRights? = null, botRightsInChat: ChatCommonAdministratorRights? = null,
botIsMember: Boolean? = null botIsMember: Boolean? = null
) = requestChatReplyButton( ) = requestChatReplyButton(
text, text,

View File

@@ -4,52 +4,52 @@ import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface UsernameChat : Chat { sealed interface UsernameChat : Chat {
val username: Username? val username: Username?
} }
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface PrivateChat : Chat, UsernameChat { sealed interface PrivateChat : Chat, UsernameChat {
override val id: UserId override val id: UserId
val firstName: String val firstName: String
val lastName: String val lastName: String
} }
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface PublicChat : Chat { sealed interface PublicChat : Chat {
val title: String val title: String
} }
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface SuperPublicChat : PublicChat, UsernameChat sealed interface SuperPublicChat : PublicChat, UsernameChat
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface ChannelChat : SuperPublicChat { sealed interface ChannelChat : SuperPublicChat {
override val id: ChatId override val id: ChatId
} }
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface GroupChat : PublicChat sealed interface GroupChat : PublicChat
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface SupergroupChat : GroupChat, SuperPublicChat sealed interface SupergroupChat : GroupChat, SuperPublicChat
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface ForumChat : SupergroupChat sealed interface ForumChat : SupergroupChat
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface PossiblyPremiumChat : Chat { sealed interface PossiblyPremiumChat : Chat {
val isPremium: Boolean val isPremium: Boolean
} }
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
sealed interface AbleToAddInAttachmentMenuChat : Chat { sealed interface AbleToAddInAttachmentMenuChat : Chat {
val addedToAttachmentMenu: Boolean val addedToAttachmentMenu: Boolean
} }
@Serializable(PreviewChatSerializer::class) @Serializable(ChatSerializer::class)
@ClassCastsIncluded @ClassCastsIncluded(excludeRegex = ".*Impl")
sealed interface Chat { sealed interface Chat {
val id: IdChatIdentifier val id: IdChatIdentifier
} }

View File

@@ -49,13 +49,54 @@ object ChatTypeSerializer : KSerializer<ChatType> {
} }
@RiskFeature @RiskFeature
object PreviewChatSerializer : KSerializer<Chat> { object ChatSerializer : KSerializer<Chat> {
@OptIn(InternalSerializationApi::class) @OptIn(InternalSerializationApi::class)
override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN) override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN)
override fun deserialize(decoder: Decoder): Chat { override fun deserialize(decoder: Decoder): Chat {
val decodedJson = JsonObject.serializer().deserialize(decoder) val decodedJson = JsonObject.serializer().deserialize(decoder)
return try {
formatter.decodeFromJsonElement(ExtendedChatSerializer, decodedJson)
} catch (e: SerializationException) {
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
val isForum = decodedJson[isForumField] ?.jsonPrimitive ?.booleanOrNull == true
when (type) {
ChatType.PrivateChatType -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson)
ChatType.GroupChatType -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson)
ChatType.SupergroupChatType -> if (isForum) {
formatter.decodeFromJsonElement(ForumChatImpl.serializer(), decodedJson)
} else {
formatter.decodeFromJsonElement(SupergroupChatImpl.serializer(), decodedJson)
}
ChatType.ChannelChatType -> formatter.decodeFromJsonElement(ChannelChatImpl.serializer(), decodedJson)
is ChatType.UnknownChatType -> UnknownChatType(
formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(),
decodedJson.toString(),
decodedJson
)
}
}
}
override fun serialize(encoder: Encoder, value: Chat) {
when (value) {
is ExtendedChat -> ExtendedChatSerializer.serialize(encoder, value)
is PreviewChat -> PreviewChatSerializer.serialize(encoder, value)
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, value)
}
}
}
@RiskFeature
object PreviewChatSerializer : KSerializer<PreviewChat> {
@OptIn(InternalSerializationApi::class)
override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN)
override fun deserialize(decoder: Decoder): PreviewChat {
val decodedJson = JsonObject.serializer().deserialize(decoder)
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson") val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
val isForum = decodedJson[isForumField] ?.jsonPrimitive ?.booleanOrNull == true val isForum = decodedJson[isForumField] ?.jsonPrimitive ?.booleanOrNull == true
@@ -76,16 +117,14 @@ object PreviewChatSerializer : KSerializer<Chat> {
} }
} }
override fun serialize(encoder: Encoder, value: Chat) { override fun serialize(encoder: Encoder, value: PreviewChat) {
when (value) { when (value) {
is ExtendedChat -> ExtendedChatSerializer.serialize(encoder, value)
is PrivateChatImpl -> PrivateChatImpl.serializer().serialize(encoder, value) is PrivateChatImpl -> PrivateChatImpl.serializer().serialize(encoder, value)
is GroupChatImpl -> GroupChatImpl.serializer().serialize(encoder, value) is GroupChatImpl -> GroupChatImpl.serializer().serialize(encoder, value)
is SupergroupChatImpl -> SupergroupChatImpl.serializer().serialize(encoder, value) is SupergroupChatImpl -> SupergroupChatImpl.serializer().serialize(encoder, value)
is ForumChatImpl -> ForumChatImpl.serializer().serialize(encoder, value) is ForumChatImpl -> ForumChatImpl.serializer().serialize(encoder, value)
is ChannelChatImpl -> ChannelChatImpl.serializer().serialize(encoder, value) is ChannelChatImpl -> ChannelChatImpl.serializer().serialize(encoder, value)
is CommonBot -> CommonBot.serializer().serialize(encoder, value) is CommonBot -> CommonBot.serializer().serialize(encoder, value)
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, value)
is CommonUser -> CommonUser.serializer().serialize(encoder, value) is CommonUser -> CommonUser.serializer().serialize(encoder, value)
is UnknownChatType -> JsonObject.serializer().serialize(encoder, value.rawJson) is UnknownChatType -> JsonObject.serializer().serialize(encoder, value.rawJson)
} }
@@ -128,6 +167,7 @@ sealed class ExtendedChatSerializer : KSerializer<ExtendedChat> {
is ExtendedSupergroupChatImpl -> ExtendedSupergroupChatImpl.serializer().serialize(encoder, value) is ExtendedSupergroupChatImpl -> ExtendedSupergroupChatImpl.serializer().serialize(encoder, value)
is ExtendedForumChatImpl -> ExtendedForumChatImpl.serializer().serialize(encoder, value) is ExtendedForumChatImpl -> ExtendedForumChatImpl.serializer().serialize(encoder, value)
is ExtendedChannelChatImpl -> ExtendedChannelChatImpl.serializer().serialize(encoder, value) is ExtendedChannelChatImpl -> ExtendedChannelChatImpl.serializer().serialize(encoder, value)
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, value)
is UnknownExtendedChat -> JsonObject.serializer().serialize(encoder, value.rawJson) is UnknownExtendedChat -> JsonObject.serializer().serialize(encoder, value.rawJson)
} }
} }

View File

@@ -3,11 +3,14 @@ package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer
import dev.inmo.tgbotapi.utils.RiskFeature
import korlibs.time.DateTime
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedChannelChat due")
data class ExtendedChannelChatImpl( data class ExtendedChannelChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: ChatId, override val id: ChatId,
@@ -33,6 +36,7 @@ data class ExtendedChannelChatImpl(
) : ExtendedChannelChat ) : ExtendedChannelChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedGroupChat due")
data class ExtendedGroupChatImpl( data class ExtendedGroupChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: ChatId, override val id: ChatId,
@@ -54,6 +58,7 @@ data class ExtendedGroupChatImpl(
) : ExtendedGroupChat ) : ExtendedGroupChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedPrivateChat due")
data class ExtendedPrivateChatImpl( data class ExtendedPrivateChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: UserId, override val id: UserId,
@@ -74,12 +79,15 @@ data class ExtendedPrivateChatImpl(
@SerialName(hasRestrictedVoiceAndVideoMessagesField) @SerialName(hasRestrictedVoiceAndVideoMessagesField)
override val hasRestrictedVoiceAndVideoMessages: Boolean = false, override val hasRestrictedVoiceAndVideoMessages: Boolean = false,
@SerialName(emojiStatusCustomEmojiIdField) @SerialName(emojiStatusCustomEmojiIdField)
override val statusEmojiId: CustomEmojiId? = null override val statusEmojiId: CustomEmojiId? = null,
@SerialName(emojiStatusExpirationDateField)
override val statusEmojiExpiration: TelegramDate? = null
) : ExtendedPrivateChat ) : ExtendedPrivateChat
typealias ExtendedUser = ExtendedPrivateChatImpl typealias ExtendedUser = ExtendedPrivateChatImpl
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedSupergroupChat due")
data class ExtendedSupergroupChatImpl( data class ExtendedSupergroupChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: ChatId, override val id: ChatId,
@@ -121,6 +129,7 @@ data class ExtendedSupergroupChatImpl(
) : ExtendedSupergroupChat ) : ExtendedSupergroupChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ExtendedForumChat due")
data class ExtendedForumChatImpl( data class ExtendedForumChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: IdChatIdentifier, override val id: IdChatIdentifier,
@@ -164,19 +173,21 @@ data class ExtendedForumChatImpl(
@Serializable @Serializable
data class ExtendedBot( data class ExtendedBot(
override val id: UserId, override val id: UserId,
@SerialName(usernameField)
override val username: Username,
@SerialName(firstNameField) @SerialName(firstNameField)
override val firstName: String, override val firstName: String,
@SerialName(lastNameField) @SerialName(lastNameField)
override val lastName: String = "", override val lastName: String = "",
@SerialName(usernameField)
override val username: Username? = null,
@SerialName(canJoinGroupsField) @SerialName(canJoinGroupsField)
val canJoinGroups: Boolean = false, val canJoinGroups: Boolean = false,
@SerialName(canReadAllGroupMessagesField) @SerialName(canReadAllGroupMessagesField)
val canReadAllGroupMessages: Boolean = false, val canReadAllGroupMessages: Boolean = false,
@SerialName(supportInlineQueriesField) @SerialName(supportInlineQueriesField)
val supportsInlineQueries: Boolean = false val supportsInlineQueries: Boolean = false,
) : Bot() { @SerialName(photoField)
override val chatPhoto: ChatPhoto? = null
) : Bot(), ExtendedChat {
@SerialName(isBotField) @SerialName(isBotField)
private val isBot = true private val isBot = true
} }

View File

@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer
import korlibs.time.DateTime
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable(ExtendedChatSerializer.Companion::class) @Serializable(ExtendedChatSerializer.Companion::class)
@@ -21,6 +22,7 @@ sealed interface ExtendedPrivateChat : PrivateChat, ExtendedChatWithUsername {
val hasPrivateForwards: Boolean val hasPrivateForwards: Boolean
val hasRestrictedVoiceAndVideoMessages: Boolean val hasRestrictedVoiceAndVideoMessages: Boolean
val statusEmojiId: CustomEmojiId? val statusEmojiId: CustomEmojiId?
val statusEmojiExpiration: TelegramDate?
val allowCreateUserIdLink: Boolean val allowCreateUserIdLink: Boolean
get() = hasPrivateForwards get() = hasPrivateForwards

View File

@@ -4,18 +4,21 @@ import dev.inmo.micro_utils.language_codes.IetfLanguageCode
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use GroupChat due")
data class GroupChatImpl( data class GroupChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: ChatId, override val id: ChatId,
@SerialName(titleField) @SerialName(titleField)
override val title: String override val title: String
) : GroupChat ) : PreviewGroupChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use PrivateChat due")
data class PrivateChatImpl( data class PrivateChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: UserId, override val id: UserId,
@@ -25,9 +28,10 @@ data class PrivateChatImpl(
override val firstName: String = "", override val firstName: String = "",
@SerialName(lastNameField) @SerialName(lastNameField)
override val lastName: String = "" override val lastName: String = ""
) : PrivateChat ) : PreviewPrivateChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use SupergroupChat due")
data class SupergroupChatImpl( data class SupergroupChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: ChatId, override val id: ChatId,
@@ -35,9 +39,10 @@ data class SupergroupChatImpl(
override val title: String, override val title: String,
@SerialName(usernameField) @SerialName(usernameField)
override val username: Username? = null override val username: Username? = null
) : SupergroupChat ) : PreviewSupergroupChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ForumChat due")
data class ForumChatImpl( data class ForumChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: IdChatIdentifier, override val id: IdChatIdentifier,
@@ -45,9 +50,10 @@ data class ForumChatImpl(
override val title: String, override val title: String,
@SerialName(usernameField) @SerialName(usernameField)
override val username: Username? = null override val username: Username? = null
) : ForumChat ) : PreviewForumChat
@Serializable @Serializable
@RiskFeature("This class is a subject of changes. It is better to use ChannelChat due")
data class ChannelChatImpl( data class ChannelChatImpl(
@SerialName(idField) @SerialName(idField)
override val id: ChatId, override val id: ChatId,
@@ -55,26 +61,30 @@ data class ChannelChatImpl(
override val title: String, override val title: String,
@SerialName(usernameField) @SerialName(usernameField)
override val username: Username? = null override val username: Username? = null
) : ChannelChat ) : PreviewChannelChat
@Serializable(UserSerializer::class) @Serializable(UserSerializer::class)
sealed class User : PrivateChat sealed class User : PrivateChat
@Serializable(UserSerializer::class) @Serializable(UserSerializer::class)
sealed class Bot : User() { sealed class PreviewUser : PreviewPrivateChat, User()
abstract override val username: Username
} @Serializable(UserSerializer::class)
sealed class Bot : User()
@Serializable(UserSerializer::class)
sealed class PreviewBot : PreviewUser()
@Serializable @Serializable
data class CommonBot( data class CommonBot(
override val id: UserId, override val id: UserId,
@SerialName(usernameField)
override val username: Username,
@SerialName(firstNameField) @SerialName(firstNameField)
override val firstName: String, override val firstName: String,
@SerialName(lastNameField) @SerialName(lastNameField)
override val lastName: String = "" override val lastName: String = "",
) : Bot() { @SerialName(usernameField)
override val username: Username? = null,
) : PreviewBot() {
@SerialName(isBotField) @SerialName(isBotField)
private val isBot = true private val isBot = true
} }
@@ -95,7 +105,7 @@ data class CommonUser(
override val isPremium: Boolean = false, override val isPremium: Boolean = false,
@SerialName(addedToAttachmentMenuField) @SerialName(addedToAttachmentMenuField)
override val addedToAttachmentMenu: Boolean = false override val addedToAttachmentMenu: Boolean = false
) : User(), WithOptionalLanguageCode, PossiblyPremiumChat, AbleToAddInAttachmentMenuChat { ) : PreviewUser(), WithOptionalLanguageCode, PossiblyPremiumChat, AbleToAddInAttachmentMenuChat {
constructor( constructor(
id: UserId, id: UserId,
firstName: String, firstName: String,

View File

@@ -0,0 +1,30 @@
package dev.inmo.tgbotapi.types.chat
import kotlinx.serialization.Serializable
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewChat : Chat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewUsernameChat : PreviewChat, UsernameChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewPrivateChat : PreviewUsernameChat, PrivateChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewPublicChat : PreviewChat, PublicChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewSuperPublicChat : PreviewPublicChat, PreviewUsernameChat, SuperPublicChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewChannelChat : PreviewSuperPublicChat, ChannelChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewGroupChat : PreviewPublicChat, GroupChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewSupergroupChat : PreviewGroupChat, PreviewSuperPublicChat, SupergroupChat
@Serializable(PreviewChatSerializer::class)
sealed interface PreviewForumChat : PreviewSupergroupChat, ForumChat

View File

@@ -7,4 +7,4 @@ data class UnknownChatType(
override val id: IdChatIdentifier, override val id: IdChatIdentifier,
val raw: String, val raw: String,
val rawJson: JsonObject val rawJson: JsonObject
) : Chat ) : Chat, PreviewChat

View File

@@ -35,9 +35,15 @@ data class AdministratorChatMemberImpl(
@SerialName(customTitleField) @SerialName(customTitleField)
override val customTitle: String? = null, override val customTitle: String? = null,
@SerialName(canManageTopicsField) @SerialName(canManageTopicsField)
override val canManageTopics: Boolean = false override val canManageTopics: Boolean = false,
@SerialName(canPostStoriesField)
override val canPostStories: Boolean = false,
@SerialName(canEditStoriesField)
override val canEditStories: Boolean = false,
@SerialName(canDeleteStoriesField)
override val canDeleteStories: Boolean = false
) : AdministratorChatMember { ) : AdministratorChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
private val type: String = "administrator" override val status: ChatMember.Status = ChatMember.Status.Administrator
} }

View File

@@ -16,4 +16,43 @@ sealed interface ChatAdministratorRights : SpecialChatAdministratorRights {
val canPromoteMembers: Boolean val canPromoteMembers: Boolean
val canPostMessages: Boolean val canPostMessages: Boolean
val canEditMessages: Boolean val canEditMessages: Boolean
val canPostStories: Boolean
val canEditStories: Boolean
val canDeleteStories: Boolean
companion object {
operator fun invoke(
canChangeInfo: Boolean = false,
canPostMessages: Boolean = false,
canEditMessages: Boolean = false,
canRemoveMessages: Boolean = false,
canInviteUsers: Boolean = false,
canRestrictMembers: Boolean = false,
canPinMessages: Boolean = false,
canPromoteMembers: Boolean = false,
canManageVideoChats: Boolean = false,
canManageChat: Boolean = false,
isAnonymous: Boolean = false,
canManageTopics: Boolean = false,
canPostStories: Boolean = false,
canEditStories: Boolean = false,
canDeleteStories: Boolean = false
) = ChatCommonAdministratorRights(
canChangeInfo = canChangeInfo,
canPostMessages = canPostMessages,
canEditMessages = canEditMessages,
canRemoveMessages = canRemoveMessages,
canInviteUsers = canInviteUsers,
canRestrictMembers = canRestrictMembers,
canPinMessages = canPinMessages,
canPromoteMembers = canPromoteMembers,
canManageVideoChats = canManageVideoChats,
canManageChat = canManageChat,
isAnonymous = isAnonymous,
canManageTopics = canManageTopics,
canPostStories = canPostStories,
canEditStories = canEditStories,
canDeleteStories = canDeleteStories
)
}
} }

View File

@@ -5,7 +5,7 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class ChatAdministratorRightsImpl( data class ChatCommonAdministratorRights(
@SerialName(canChangeInfoField) @SerialName(canChangeInfoField)
override val canChangeInfo: Boolean = false, override val canChangeInfo: Boolean = false,
@SerialName(canPostMessagesField) @SerialName(canPostMessagesField)
@@ -29,5 +29,20 @@ data class ChatAdministratorRightsImpl(
@SerialName(isAnonymousField) @SerialName(isAnonymousField)
override val isAnonymous: Boolean = false, override val isAnonymous: Boolean = false,
@SerialName(canManageTopicsField) @SerialName(canManageTopicsField)
override val canManageTopics: Boolean = false override val canManageTopics: Boolean = false,
@SerialName(canPostStoriesField)
override val canPostStories: Boolean = false,
@SerialName(canEditStoriesField)
override val canEditStories: Boolean = false,
@SerialName(canDeleteStoriesField)
override val canDeleteStories: Boolean = false
) : ChatAdministratorRights ) : ChatAdministratorRights
@Deprecated(
"Renamed to ChatCommonAdministratorRights and will be removed soon",
ReplaceWith(
"ChatCommonAdministratorRights",
"dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights"
)
)
typealias ChatAdministratorRightsImpl = ChatCommonAdministratorRights

View File

@@ -4,8 +4,10 @@ import dev.inmo.tgbotapi.abstracts.WithUser
import dev.inmo.tgbotapi.types.statusField import dev.inmo.tgbotapi.types.statusField
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.DeserializationStrategy
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@@ -13,7 +15,38 @@ import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
@Serializable(ChatMemberSerializer::class) @Serializable(ChatMemberSerializer::class)
sealed interface ChatMember : WithUser sealed interface ChatMember : WithUser {
@Serializable(StatusSerializer::class)
enum class Status(
val status: String,
val deserializationStrategy: DeserializationStrategy<ChatMember>
) {
Creator("creator", OwnerChatMember.serializer()),
Administrator("administrator", AdministratorChatMemberImpl.serializer()),
Member("member", MemberChatMemberImpl.serializer()),
Restricted("restricted", RestrictedChatMember.serializer()),
Left("left", LeftChatMemberImpl.serializer()),
Kicked("kicked", KickedChatMember.serializer())
}
object StatusSerializer : KSerializer<Status> {
override val descriptor: SerialDescriptor
get() = String.serializer().descriptor
override fun deserialize(decoder: Decoder): Status {
val status = decoder.decodeString()
return Status.values().first {
it.status == status
}
}
override fun serialize(encoder: Encoder, value: Status) {
encoder.encodeString(value.status)
}
}
val status: Status
}
@RiskFeature @RiskFeature
object ChatMemberSerializer : KSerializer<ChatMember> { object ChatMemberSerializer : KSerializer<ChatMember> {
@@ -21,15 +54,14 @@ object ChatMemberSerializer : KSerializer<ChatMember> {
override fun deserialize(decoder: Decoder): ChatMember { override fun deserialize(decoder: Decoder): ChatMember {
val json = JsonObject.serializer().deserialize(decoder) val json = JsonObject.serializer().deserialize(decoder)
return when (json[statusField] ?.jsonPrimitive ?.content ?: error("Status field of chat member must be specified, but incoming json contains next: $json")) { val status = json[statusField] ?.jsonPrimitive ?.content ?: error("Status field of chat member must be specified, but incoming json contains next: $json")
"creator" -> nonstrictJsonFormat.decodeFromJsonElement(OwnerChatMember.serializer(), json) return ChatMember.Status.values().firstNotNullOfOrNull {
"administrator" -> nonstrictJsonFormat.decodeFromJsonElement(AdministratorChatMemberImpl.serializer(), json) if (it.status == status) {
"member" -> nonstrictJsonFormat.decodeFromJsonElement(MemberChatMemberImpl.serializer(), json) nonstrictJsonFormat.decodeFromJsonElement(it.deserializationStrategy, json)
"restricted" -> nonstrictJsonFormat.decodeFromJsonElement(RestrictedChatMember.serializer(), json) } else {
"left" -> nonstrictJsonFormat.decodeFromJsonElement(LeftChatMemberImpl.serializer(), json) null
"kicked" -> nonstrictJsonFormat.decodeFromJsonElement(KickedChatMember.serializer(), json) }
else -> error("Unknown type of chat member in json: $json") } ?: error("Unknown type of chat member in json: $json")
}
} }
override fun serialize(encoder: Encoder, value: ChatMember) { override fun serialize(encoder: Encoder, value: ChatMember) {

View File

@@ -1,9 +1,10 @@
package dev.inmo.tgbotapi.types.chat.member package dev.inmo.tgbotapi.types.chat.member
import dev.inmo.tgbotapi.abstracts.WithChat import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.abstracts.WithUser import dev.inmo.tgbotapi.abstracts.WithUser
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.chat.User import dev.inmo.tgbotapi.types.chat.User
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -11,7 +12,7 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class ChatMemberUpdated( data class ChatMemberUpdated(
@SerialName(chatField) @SerialName(chatField)
override val chat: Chat, override val chat: PreviewChat,
@SerialName(fromField) @SerialName(fromField)
override val user: User, override val user: User,
@SerialName(dateField) @SerialName(dateField)
@@ -24,4 +25,4 @@ data class ChatMemberUpdated(
val inviteLink: ChatInviteLink? = null, val inviteLink: ChatInviteLink? = null,
@SerialName(viaChatFolderInviteLinkField) @SerialName(viaChatFolderInviteLinkField)
val viaChatFolderInviteLink: Boolean? = false val viaChatFolderInviteLink: Boolean? = false
) : WithChat, WithUser ) : WithPreviewChat, WithUser

View File

@@ -13,5 +13,5 @@ data class KickedChatMember(
) : BannedChatMember { ) : BannedChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
private val type: String = "kicked" override val status: ChatMember.Status = ChatMember.Status.Kicked
} }

View File

@@ -5,8 +5,11 @@ import dev.inmo.tgbotapi.types.chat.User
import kotlinx.serialization.* import kotlinx.serialization.*
@Serializable @Serializable
data class LeftChatMemberImpl(@SerialName(userField) override val user: User) : LeftChatMember { data class LeftChatMemberImpl(
@SerialName(userField)
override val user: User
) : LeftChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
private val type: String = "left" override val status: ChatMember.Status = ChatMember.Status.Left
} }

View File

@@ -5,8 +5,11 @@ import dev.inmo.tgbotapi.types.chat.User
import kotlinx.serialization.* import kotlinx.serialization.*
@Serializable @Serializable
data class MemberChatMemberImpl(@SerialName(userField) override val user: User) : MemberChatMember { data class MemberChatMemberImpl(
@SerialName(userField)
override val user: User
) : MemberChatMember {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
private val type: String = "member" override val status: ChatMember.Status = ChatMember.Status.Member
} }

View File

@@ -36,7 +36,14 @@ data class OwnerChatMember(
override val canManageChat: Boolean = true override val canManageChat: Boolean = true
@Transient @Transient
override val canManageTopics: Boolean = true override val canManageTopics: Boolean = true
@Transient
override val canPostStories: Boolean = true
@Transient
override val canEditStories: Boolean = true
@Transient
override val canDeleteStories: Boolean = true
@SerialName(statusField) @SerialName(statusField)
@Required @Required
private val type: String = "creator" override val status: ChatMember.Status = ChatMember.Status.Creator
} }

View File

@@ -44,5 +44,5 @@ data class RestrictedChatMember(
) : BannedChatMember, SpecialRightsChatMember, ChatPermissions { ) : BannedChatMember, SpecialRightsChatMember, ChatPermissions {
@SerialName(statusField) @SerialName(statusField)
@Required @Required
private val type: String = "restricted" override val status: ChatMember.Status = ChatMember.Status.Restricted
} }

View File

@@ -5,12 +5,13 @@ import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.ChannelChat import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.chat.CommonBot import dev.inmo.tgbotapi.types.chat.CommonBot
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
import dev.inmo.tgbotapi.types.message.abstracts.* import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
data class ChannelContentMessageImpl<T: MessageContent>( data class ChannelContentMessageImpl<T: MessageContent>(
override val messageId: MessageId, override val messageId: MessageId,
override val chat: ChannelChat, override val chat: PreviewChannelChat,
override val content: T, override val content: T,
override val date: DateTime, override val date: DateTime,
override val editDate: DateTime?, override val editDate: DateTime?,

View File

@@ -3,12 +3,13 @@ package dev.inmo.tgbotapi.types.message
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.ChannelChat import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
data class ChannelEventMessage<T : ChannelEvent>( data class ChannelEventMessage<T : ChannelEvent>(
override val messageId: MessageId, override val messageId: MessageId,
override val chat: ChannelChat, override val chat: PreviewChannelChat,
override val chatEvent: T, override val chatEvent: T,
override val date: DateTime override val date: DateTime
) : ChatEventMessage<T> ) : ChatEventMessage<T>

View File

@@ -1,12 +1,75 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.forum package dev.inmo.tgbotapi.types.message.ChatEvents.forum
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ForumEvent
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent
import dev.inmo.tgbotapi.types.webAppNameField import dev.inmo.tgbotapi.types.webAppNameField
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializable @Serializable(WriteAccessAllowed.Companion::class)
data class WriteAccessAllowed( sealed interface WriteAccessAllowed : PrivateEvent, ForumEvent {
@SerialName(webAppNameField) val webAppName: String?
val webAppName: String? = null get() = null
) : ForumEvent val fromRequest: Boolean
get() = false
val fromAttachmentMenu: Boolean
get() = false
@Serializable
object Other : WriteAccessAllowed
@Serializable
data class FromWebAppLink(
override val webAppName: String
) : WriteAccessAllowed
@Serializable
object FromRequest : WriteAccessAllowed {
override val fromRequest: Boolean
get() = true
}
@Serializable
object FromAttachmentMenu : WriteAccessAllowed {
override val fromAttachmentMenu: Boolean
get() = true
}
@Serializable
private class WriteAccessAllowedRaw(
val web_app_name: String? = null,
val from_request: Boolean = false,
val from_attachment_menu: Boolean = false
)
companion object : KSerializer<WriteAccessAllowed> {
override val descriptor: SerialDescriptor
get() = WriteAccessAllowedRaw.serializer().descriptor
override fun deserialize(decoder: Decoder): WriteAccessAllowed {
val raw = WriteAccessAllowedRaw.serializer().deserialize(decoder)
return when {
raw.web_app_name != null -> FromWebAppLink(raw.web_app_name)
raw.from_request -> FromRequest
raw.from_attachment_menu -> Other
else -> Other
}
}
override fun serialize(encoder: Encoder, value: WriteAccessAllowed) {
val raw = when (value) {
FromAttachmentMenu -> WriteAccessAllowedRaw(from_attachment_menu = true)
FromRequest -> WriteAccessAllowedRaw(from_request = true)
Other -> WriteAccessAllowedRaw()
is FromWebAppLink -> WriteAccessAllowedRaw(web_app_name = value.webAppName)
}
WriteAccessAllowedRaw.serializer().serialize(encoder, raw)
}
operator fun invoke(webAppName: String?): WriteAccessAllowed = webAppName ?.let(::FromWebAppLink) ?: Other
}
}

View File

@@ -4,13 +4,14 @@ import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.GroupChat import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent
import dev.inmo.tgbotapi.types.message.abstracts.GroupEventMessage import dev.inmo.tgbotapi.types.message.abstracts.GroupEventMessage
data class CommonGroupEventMessage<T : GroupEvent>( data class CommonGroupEventMessage<T : GroupEvent>(
override val messageId: MessageId, override val messageId: MessageId,
override val from: User, override val from: User,
override val chat: GroupChat, override val chat: PreviewGroupChat,
override val chatEvent: T, override val chatEvent: T,
override val date: DateTime override val date: DateTime
) : GroupEventMessage<T> ) : GroupEventMessage<T>

View File

@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.message
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
import dev.inmo.tgbotapi.types.chat.User import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.SupergroupChat import dev.inmo.tgbotapi.types.chat.SupergroupChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
@@ -10,7 +11,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
data class CommonSupergroupEventMessage<T : SupergroupEvent>( data class CommonSupergroupEventMessage<T : SupergroupEvent>(
override val messageId: MessageId, override val messageId: MessageId,
override val from: User, override val from: User,
override val chat: SupergroupChat, override val chat: PreviewSupergroupChat,
override val chatEvent: T, override val chatEvent: T,
override val date: DateTime override val date: DateTime
) : SupergroupEventMessage<T> ) : SupergroupEventMessage<T>

View File

@@ -10,8 +10,8 @@ import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
data class ConnectedFromChannelGroupContentMessageImpl<T : MessageContent>( data class ConnectedFromChannelGroupContentMessageImpl<T : MessageContent>(
override val chat: GroupChat, override val chat: PreviewGroupChat,
override val channel: ChannelChat, override val channel: PreviewChannelChat,
override val messageId: MessageId, override val messageId: MessageId,
override val date: DateTime, override val date: DateTime,
override val forwardInfo: ForwardInfo?, override val forwardInfo: ForwardInfo?,
@@ -26,8 +26,8 @@ data class ConnectedFromChannelGroupContentMessageImpl<T : MessageContent>(
) : ConnectedFromChannelGroupContentMessage<T> ) : ConnectedFromChannelGroupContentMessage<T>
data class UnconnectedFromChannelGroupContentMessageImpl<T: MessageContent>( data class UnconnectedFromChannelGroupContentMessageImpl<T: MessageContent>(
override val chat: GroupChat, override val chat: PreviewGroupChat,
override val channel: ChannelChat, override val channel: PreviewChannelChat,
override val messageId: MessageId, override val messageId: MessageId,
override val date: DateTime, override val date: DateTime,
override val forwardInfo: ForwardInfo?, override val forwardInfo: ForwardInfo?,
@@ -42,7 +42,7 @@ data class UnconnectedFromChannelGroupContentMessageImpl<T: MessageContent>(
) : UnconnectedFromChannelGroupContentMessage<T> ) : UnconnectedFromChannelGroupContentMessage<T>
data class AnonymousGroupContentMessageImpl<T : MessageContent>( data class AnonymousGroupContentMessageImpl<T : MessageContent>(
override val chat: GroupChat, override val chat: PreviewGroupChat,
override val messageId: MessageId, override val messageId: MessageId,
override val date: DateTime, override val date: DateTime,
override val forwardInfo: ForwardInfo?, override val forwardInfo: ForwardInfo?,
@@ -57,7 +57,7 @@ data class AnonymousGroupContentMessageImpl<T : MessageContent>(
) : AnonymousGroupContentMessage<T> ) : AnonymousGroupContentMessage<T>
data class CommonGroupContentMessageImpl<T : MessageContent>( data class CommonGroupContentMessageImpl<T : MessageContent>(
override val chat: GroupChat, override val chat: PreviewGroupChat,
override val messageId: MessageId, override val messageId: MessageId,
override val from: User, override val from: User,
override val date: DateTime, override val date: DateTime,
@@ -72,8 +72,8 @@ data class CommonGroupContentMessageImpl<T : MessageContent>(
) : CommonGroupContentMessage<T> ) : CommonGroupContentMessage<T>
data class FromChannelForumContentMessageImpl<T: MessageContent>( data class FromChannelForumContentMessageImpl<T: MessageContent>(
override val chat: ForumChat, override val chat: PreviewForumChat,
override val channel: ChannelChat, override val channel: PreviewChannelChat,
override val messageId: MessageId, override val messageId: MessageId,
override val threadId: MessageThreadId, override val threadId: MessageThreadId,
override val date: DateTime, override val date: DateTime,
@@ -89,7 +89,7 @@ data class FromChannelForumContentMessageImpl<T: MessageContent>(
) : FromChannelForumContentMessage<T> ) : FromChannelForumContentMessage<T>
data class AnonymousForumContentMessageImpl<T : MessageContent>( data class AnonymousForumContentMessageImpl<T : MessageContent>(
override val chat: ForumChat, override val chat: PreviewForumChat,
override val messageId: MessageId, override val messageId: MessageId,
override val threadId: MessageThreadId, override val threadId: MessageThreadId,
override val date: DateTime, override val date: DateTime,
@@ -105,7 +105,7 @@ data class AnonymousForumContentMessageImpl<T : MessageContent>(
) : AnonymousForumContentMessage<T> ) : AnonymousForumContentMessage<T>
data class CommonForumContentMessageImpl<T : MessageContent>( data class CommonForumContentMessageImpl<T : MessageContent>(
override val chat: ForumChat, override val chat: PreviewForumChat,
override val messageId: MessageId, override val messageId: MessageId,
override val threadId: MessageThreadId, override val threadId: MessageThreadId,
override val from: User, override val from: User,

View File

@@ -4,13 +4,14 @@ import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.message.abstracts.FromUserMessage import dev.inmo.tgbotapi.types.message.abstracts.FromUserMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.passport.PassportData import dev.inmo.tgbotapi.types.passport.PassportData
data class PassportMessage( data class PassportMessage(
override val messageId: MessageId, override val messageId: MessageId,
override val chat: Chat, override val chat: PreviewChat,
override val from: User, override val from: User,
override val date: DateTime, override val date: DateTime,
val passportData: PassportData val passportData: PassportData

View File

@@ -13,7 +13,7 @@ import dev.inmo.tgbotapi.types.message.content.MessageContent
data class PrivateContentMessageImpl<T: MessageContent>( data class PrivateContentMessageImpl<T: MessageContent>(
override val messageId: MessageId, override val messageId: MessageId,
override val from: User, override val from: User,
override val chat: Chat, override val chat: PreviewPrivateChat,
override val content: T, override val content: T,
override val date: DateTime, override val date: DateTime,
override val editDate: DateTime?, override val editDate: DateTime?,

View File

@@ -2,13 +2,14 @@ package dev.inmo.tgbotapi.types.message
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
import dev.inmo.tgbotapi.types.chat.PrivateChat import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
data class PrivateEventMessage<T : PrivateEvent>( data class PrivateEventMessage<T : PrivateEvent>(
override val messageId: MessageId, override val messageId: MessageId,
override val chat: PrivateChat, override val chat: PreviewPrivateChat,
override val chatEvent: T, override val chatEvent: T,
override val date: DateTime override val date: DateTime
) : ChatEventMessage<T> ) : ChatEventMessage<T>

View File

@@ -31,6 +31,7 @@ import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
import dev.inmo.tgbotapi.types.polls.Poll import dev.inmo.tgbotapi.types.polls.Poll
import dev.inmo.tgbotapi.types.request.ChatShared import dev.inmo.tgbotapi.types.request.ChatShared
import dev.inmo.tgbotapi.types.request.UserShared import dev.inmo.tgbotapi.types.request.UserShared
import dev.inmo.tgbotapi.types.stories.Story
import dev.inmo.tgbotapi.types.venue.Venue import dev.inmo.tgbotapi.types.venue.Venue
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -42,11 +43,11 @@ internal data class RawMessage(
@SerialName(messageIdField) @SerialName(messageIdField)
val messageId: MessageId, val messageId: MessageId,
val date: TelegramDate, val date: TelegramDate,
private val chat: Chat, private val chat: PreviewChat,
@SerialName(messageThreadIdField) @SerialName(messageThreadIdField)
private val messageThreadId: MessageThreadId? = null, private val messageThreadId: MessageThreadId? = null,
private val from: User? = null, private val from: User? = null,
private val sender_chat: PublicChat? = null, private val sender_chat: PreviewPublicChat? = null,
private val forward_from: User? = null, private val forward_from: User? = null,
private val forward_from_chat: Chat? = null, private val forward_from_chat: Chat? = null,
private val forward_from_message_id: MessageId? = null, private val forward_from_message_id: MessageId? = null,
@@ -65,6 +66,7 @@ internal data class RawMessage(
private val caption: String? = null, private val caption: String? = null,
private val caption_entities: RawMessageEntities? = null, private val caption_entities: RawMessageEntities? = null,
private val has_media_spoiler: Boolean? = null, private val has_media_spoiler: Boolean? = null,
private val story: Story? = null,
private val audio: AudioFile? = null, private val audio: AudioFile? = null,
private val document: DocumentFile? = null, private val document: DocumentFile? = null,
private val animation: AnimationFile? = null, private val animation: AnimationFile? = null,
@@ -134,6 +136,11 @@ internal data class RawMessage(
} ?: emptyList() } ?: emptyList()
when { when {
story != null -> StoryContent(
chat,
messageId,
story
)
text != null -> TextContent(text, (entities ?: emptyList()).asTextSources(text)) text != null -> TextContent(text, (entities ?: emptyList()).asTextSources(text))
audio != null -> AudioContent( audio != null -> AudioContent(
audio, audio,
@@ -267,27 +274,27 @@ internal data class RawMessage(
try { try {
chatEvent?.let { chatEvent -> chatEvent?.let { chatEvent ->
when (chat) { when (chat) {
is SupergroupChat -> CommonSupergroupEventMessage( is PreviewSupergroupChat -> CommonSupergroupEventMessage(
messageId, messageId,
from ?: error("Supergroup events are expected to contain 'from' field"), from ?: error("Supergroup events are expected to contain 'from' field"),
chat, chat,
chatEvent as? SupergroupEvent ?: throwWrongChatEvent(SupergroupEvent::class, chatEvent), chatEvent as? SupergroupEvent ?: throwWrongChatEvent(SupergroupEvent::class, chatEvent),
date.asDate date.asDate
) )
is GroupChat -> CommonGroupEventMessage( is PreviewGroupChat -> CommonGroupEventMessage(
messageId, messageId,
from ?: error("Supergroup events are expected to contain 'from' field"), from ?: error("Supergroup events are expected to contain 'from' field"),
chat, chat,
chatEvent as? GroupEvent ?: throwWrongChatEvent(GroupChat::class, chatEvent), chatEvent as? GroupEvent ?: throwWrongChatEvent(GroupChat::class, chatEvent),
date.asDate date.asDate
) )
is ChannelChat -> ChannelEventMessage( is PreviewChannelChat -> ChannelEventMessage(
messageId, messageId,
chat, chat,
chatEvent as? ChannelEvent ?: throwWrongChatEvent(ChannelEvent::class, chatEvent), chatEvent as? ChannelEvent ?: throwWrongChatEvent(ChannelEvent::class, chatEvent),
date.asDate date.asDate
) )
is PrivateChat -> PrivateEventMessage( is PreviewPrivateChat -> PrivateEventMessage(
messageId, messageId,
chat, chat,
chatEvent as? PrivateEvent ?: throwWrongChatEvent(PrivateEvent::class, chatEvent), chatEvent as? PrivateEvent ?: throwWrongChatEvent(PrivateEvent::class, chatEvent),
@@ -296,8 +303,8 @@ internal data class RawMessage(
else -> error("Expected one of the public chats, but was $chat (in extracting of chat event message)") else -> error("Expected one of the public chats, but was $chat (in extracting of chat event message)")
} }
} ?: content?.let { content -> when (chat) { } ?: content?.let { content -> when (chat) {
is PublicChat -> when (chat) { is PreviewPublicChat -> when (chat) {
is ChannelChat -> ChannelContentMessageImpl( is PreviewChannelChat -> ChannelContentMessageImpl(
messageId, messageId,
chat, chat,
content, content,
@@ -311,17 +318,16 @@ internal data class RawMessage(
author_signature, author_signature,
media_group_id media_group_id
) )
is ForumChat -> if (messageThreadId != null) { is PreviewForumChat -> if (messageThreadId != null) {
val chatId = ChatIdWithThreadId( val chatId = ChatIdWithThreadId(
chat.id.chatId, chat.id.chatId,
messageThreadId messageThreadId
) )
val actualForumChat = when (chat) { val actualForumChat = when (chat) {
is ExtendedForumChatImpl -> chat.copy(id = chatId)
is ForumChatImpl -> chat.copy(id = chatId) is ForumChatImpl -> chat.copy(id = chatId)
} }
when (sender_chat) { when (sender_chat) {
is ChannelChat -> FromChannelForumContentMessageImpl( is PreviewChannelChat -> FromChannelForumContentMessageImpl(
actualForumChat, actualForumChat,
sender_chat, sender_chat,
messageId, messageId,
@@ -337,7 +343,7 @@ internal data class RawMessage(
author_signature, author_signature,
media_group_id media_group_id
) )
is GroupChat -> AnonymousForumContentMessageImpl( is PreviewGroupChat -> AnonymousForumContentMessageImpl(
actualForumChat, actualForumChat,
messageId, messageId,
messageThreadId, messageThreadId,
@@ -370,7 +376,7 @@ internal data class RawMessage(
} }
} else { } else {
when (sender_chat) { when (sender_chat) {
is ChannelChat -> if (is_automatic_forward == true) { is PreviewChannelChat -> if (is_automatic_forward == true) {
ConnectedFromChannelGroupContentMessageImpl( ConnectedFromChannelGroupContentMessageImpl(
chat, chat,
sender_chat, sender_chat,
@@ -433,8 +439,8 @@ internal data class RawMessage(
) )
} }
} }
is GroupChat -> when (sender_chat) { is PreviewGroupChat -> when (sender_chat) {
is ChannelChat -> if (is_automatic_forward == true) { is PreviewChannelChat -> if (is_automatic_forward == true) {
ConnectedFromChannelGroupContentMessageImpl( ConnectedFromChannelGroupContentMessageImpl(
chat, chat,
sender_chat, sender_chat,
@@ -467,7 +473,7 @@ internal data class RawMessage(
media_group_id media_group_id
) )
} }
is GroupChat -> AnonymousGroupContentMessageImpl( is PreviewGroupChat -> AnonymousGroupContentMessageImpl(
chat, chat,
messageId, messageId,
date.asDate, date.asDate,
@@ -497,7 +503,7 @@ internal data class RawMessage(
) )
} }
} }
is PrivateChat -> PrivateContentMessageImpl( is PreviewPrivateChat -> PrivateContentMessageImpl(
messageId, messageId,
from ?: error("Was detected common message, but owner (sender) of the message was not found"), from ?: error("Was detected common message, but owner (sender) of the message was not found"),
chat, chat,

View File

@@ -18,6 +18,30 @@ internal data class RawMessageEntity(
internal val range by lazy { internal val range by lazy {
offset until (offset + length) offset until (offset + length)
} }
val priority by lazy {
when (type) {
// Types with potential subsources should have priority
"mention" -> 0
"hashtag" -> 0
"cashtag" -> 0
"email" -> 0
"phone_number" -> 0
"bold" -> 0
"italic" -> 0
"text_mention" -> 0
"strikethrough" -> 0
"underline" -> 0
"spoiler" -> 0
"custom_emoji" -> 0
"bot_command" -> 1
"url" -> 1
"code" -> 1
"pre" -> 1
"text_link" -> 1
else -> 1
}
}
} }
internal fun RawMessageEntity.asTextSource( internal fun RawMessageEntity.asTextSource(
@@ -85,7 +109,10 @@ private fun createTextSources(
originalFullString: String, originalFullString: String,
entities: RawMessageEntities entities: RawMessageEntities
): List<Pair<Int, TextSource>> { ): List<Pair<Int, TextSource>> {
val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } } val mutableEntities = entities.toMutableList().apply {
sortBy { it.priority } // sorting to fix potential issues in source sorting of entities
sortBy { it.offset }
}
val resultList = mutableListOf<Pair<Int, TextSource>>() val resultList = mutableListOf<Pair<Int, TextSource>>()
while (mutableEntities.isNotEmpty()) { while (mutableEntities.isNotEmpty()) {

View File

@@ -1,10 +1,11 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.chat.ChannelChat import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
interface ChannelContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, SignedMessage, WithSenderChatMessage { interface ChannelContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, SignedMessage, WithSenderChatMessage {
override val chat: ChannelChat override val chat: PreviewChannelChat
override val senderChat: ChannelChat override val senderChat: PreviewChannelChat
get() = chat get() = chat
} }

View File

@@ -1,5 +1,9 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent
interface GroupEventMessage<T : GroupEvent> : ChatEventMessage<T>, FromUserMessage interface GroupEventMessage<T : GroupEvent> : ChatEventMessage<T>, FromUserMessage {
override val chat: PreviewGroupChat
}

View File

@@ -1,24 +1,22 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.MessageThreadId import dev.inmo.tgbotapi.types.MessageThreadId
import dev.inmo.tgbotapi.types.chat.ChannelChat import dev.inmo.tgbotapi.types.chat.*
import dev.inmo.tgbotapi.types.chat.ForumChat
import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
sealed interface GroupContentMessage<T : MessageContent> : PublicContentMessage<T> { sealed interface GroupContentMessage<T : MessageContent> : PublicContentMessage<T> {
override val chat: GroupChat override val chat: PreviewGroupChat
} }
sealed interface ForumContentMessage<T : MessageContent> : GroupContentMessage<T>, PossiblyTopicMessage { sealed interface ForumContentMessage<T : MessageContent> : GroupContentMessage<T>, PossiblyTopicMessage {
override val chat: ForumChat override val chat: PreviewForumChat
override val threadId: MessageThreadId override val threadId: MessageThreadId
} }
sealed interface FromChannelGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage { sealed interface FromChannelGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage {
val channel: ChannelChat val channel: PreviewChannelChat
override val senderChat: ChannelChat override val senderChat: PreviewChannelChat
get() = channel get() = channel
} }
@@ -26,7 +24,7 @@ interface ConnectedFromChannelGroupContentMessage<T: MessageContent> : FromChann
interface UnconnectedFromChannelGroupContentMessage<T: MessageContent> : FromChannelGroupContentMessage<T> interface UnconnectedFromChannelGroupContentMessage<T: MessageContent> : FromChannelGroupContentMessage<T>
interface AnonymousGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage { interface AnonymousGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage {
override val senderChat: GroupChat override val senderChat: PreviewGroupChat
get() = chat get() = chat
} }
@@ -35,7 +33,7 @@ interface CommonGroupContentMessage<T : MessageContent> : GroupContentMessage<T>
interface FromChannelForumContentMessage<T: MessageContent> : FromChannelGroupContentMessage<T>, ForumContentMessage<T> interface FromChannelForumContentMessage<T: MessageContent> : FromChannelGroupContentMessage<T>, ForumContentMessage<T>
interface AnonymousForumContentMessage<T : MessageContent> : ForumContentMessage<T>, SignedMessage, WithSenderChatMessage { interface AnonymousForumContentMessage<T : MessageContent> : ForumContentMessage<T>, SignedMessage, WithSenderChatMessage {
override val senderChat: GroupChat override val senderChat: PreviewGroupChat
get() = chat get() = chat
} }

View File

@@ -1,25 +1,26 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.WithChat import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.message.RawMessage import dev.inmo.tgbotapi.types.message.RawMessage
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.descriptors.* import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@ClassCastsIncluded @ClassCastsIncluded(excludeRegex = ".*Impl")
interface Message : WithChat { interface Message : WithPreviewChat {
val messageId: MessageId val messageId: MessageId
val date: DateTime val date: DateTime
} }
data class UnknownMessageType( data class UnknownMessageType(
override val messageId: MessageId, override val messageId: MessageId,
override val chat: Chat, override val chat: PreviewChat,
override val date: DateTime, override val date: DateTime,
val insideException: Exception val insideException: Exception
) : Message ) : Message

View File

@@ -1,5 +1,9 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
interface PrivateContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, FromUserMessage interface PrivateContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, FromUserMessage {
override val chat: PreviewPrivateChat
}

View File

@@ -1,8 +1,9 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.chat.PreviewPublicChat
import dev.inmo.tgbotapi.types.chat.PublicChat import dev.inmo.tgbotapi.types.chat.PublicChat
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
sealed interface PublicContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T> { sealed interface PublicContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T> {
override val chat: PublicChat override val chat: PreviewPublicChat
} }

View File

@@ -1,5 +1,9 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
import dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
interface SupergroupEventMessage<T : SupergroupEvent> : GroupEventMessage<T> interface SupergroupEventMessage<T : SupergroupEvent> : GroupEventMessage<T> {
override val chat: PreviewSupergroupChat
}

View File

@@ -1,7 +1,8 @@
package dev.inmo.tgbotapi.types.message.abstracts package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PreviewChat
interface WithSenderChatMessage { interface WithSenderChatMessage {
val senderChat: Chat val senderChat: PreviewChat
} }

View File

@@ -13,8 +13,10 @@ import dev.inmo.tgbotapi.types.media.TelegramMedia
import dev.inmo.tgbotapi.types.message.abstracts.* import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.threadId import dev.inmo.tgbotapi.types.threadId
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.Serializable
import kotlinx.serialization.modules.* import kotlinx.serialization.modules.*
@Serializable
sealed interface MessageContent: ResendableContent { sealed interface MessageContent: ResendableContent {
companion object { companion object {
@RiskFeature("This serialization module can be changed in near releases") @RiskFeature("This serialization module can be changed in near releases")
@@ -49,6 +51,7 @@ sealed interface MessageContent: ResendableContent {
subclass(AnimationContent::class) subclass(AnimationContent::class)
subclass(StickerContent::class) subclass(StickerContent::class)
subclass(InvoiceContent::class) subclass(InvoiceContent::class)
subclass(StoryContent::class)
additionalBuilder() additionalBuilder()
} }

View File

@@ -58,7 +58,6 @@ sealed interface LocationContent : MessageContent {
/** /**
* [KSerializer] for [LocationContent] * [KSerializer] for [LocationContent]
*/ */
@Serializer(LocationContent::class)
object LocationContentSerializer : KSerializer<LocationContent> { object LocationContentSerializer : KSerializer<LocationContent> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("LocationContent") { override val descriptor: SerialDescriptor = buildClassSerialDescriptor("LocationContent") {
element(LocationContent::location.name, LocationSerializer.descriptor) element(LocationContent::location.name, LocationSerializer.descriptor)
@@ -85,7 +84,6 @@ object LocationContentSerializer : KSerializer<LocationContent> {
encodeSerializableElement(descriptor, 0, LocationSerializer, value.location) encodeSerializableElement(descriptor, 0, LocationSerializer, value.location)
}.endStructure(descriptor) }.endStructure(descriptor)
} }
} }
/** /**
@@ -94,7 +92,7 @@ object LocationContentSerializer : KSerializer<LocationContent> {
* *
* @see dev.inmo.tgbotapi.extensions.behaviour_builder.utils.followLocation * @see dev.inmo.tgbotapi.extensions.behaviour_builder.utils.followLocation
*/ */
@Serializable(LocationContentSerializer::class) @Serializable
data class LiveLocationContent( data class LiveLocationContent(
override val location: LiveLocation override val location: LiveLocation
) : LocationContent { ) : LocationContent {
@@ -127,7 +125,7 @@ data class LiveLocationContent(
* Just a [LocationContent] with [StaticLocation] [location]. It could be [LiveLocationContent] in previous time in case * Just a [LocationContent] with [StaticLocation] [location]. It could be [LiveLocationContent] in previous time in case
* when somebody has sent [LiveLocation] in chat and then stop to broadcast location * when somebody has sent [LiveLocation] in chat and then stop to broadcast location
*/ */
@Serializable(LocationContentSerializer::class) @Serializable
data class StaticLocationContent( data class StaticLocationContent(
override val location: StaticLocation override val location: StaticLocation
) : LocationContent { ) : LocationContent {

View File

@@ -0,0 +1,40 @@
package dev.inmo.tgbotapi.types.message.content
import dev.inmo.tgbotapi.requests.ForwardMessage
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.MessageThreadId
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyForwardedMessage
import dev.inmo.tgbotapi.types.stories.Story
import kotlinx.serialization.Serializable
@Serializable
data class StoryContent(
private val chat: Chat,
private val messageId: MessageId,
val story: Story
) : MessageContent {
override fun createResend(
chatId: ChatIdentifier,
messageThreadId: MessageThreadId?,
disableNotification: Boolean,
protectContent: Boolean,
replyToMessageId: MessageId?,
allowSendingWithoutReply: Boolean?,
replyMarkup: KeyboardMarkup?
): Request<PossiblyForwardedMessage> {
return ForwardMessage(
chat.id,
toChatId = chatId,
messageId = messageId,
threadId = messageThreadId,
disableNotification = disableNotification,
protectContent = protectContent
)
}
}

View File

@@ -11,6 +11,7 @@ typealias DiceMessage = CommonMessage<DiceContent>
typealias ContactMessage = CommonMessage<ContactContent> typealias ContactMessage = CommonMessage<ContactContent>
typealias PollMessage = CommonMessage<PollContent> typealias PollMessage = CommonMessage<PollContent>
typealias TextMessage = CommonMessage<TextContent> typealias TextMessage = CommonMessage<TextContent>
typealias StoryMessage = CommonMessage<StoryContent>
typealias LocationMessage = CommonMessage<LocationContent> typealias LocationMessage = CommonMessage<LocationContent>
typealias LiveLocationMessage = CommonMessage<LiveLocationContent> typealias LiveLocationMessage = CommonMessage<LiveLocationContent>

Some files were not shown because too many files have changed in this diff Show More