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

Compare commits

..

143 Commits
1.1.1 ... 3.1.0

Author SHA1 Message Date
cd62a9ef3c fixes 2022-08-13 14:40:00 +06:00
3c084d70e5 fix of #588 2022-08-13 13:13:07 +06:00
2611d4ecc1 fill changelog with dependnecies updates 2022-08-13 13:06:18 +06:00
b4d853dfa0 update bot api support info 2022-08-13 13:03:34 +06:00
5044075adf add support of sticker_type for new sticker sets and rework create new sticker set requests 2022-08-13 13:01:09 +06:00
5f2660b804 fill raw sticker data 2022-08-13 12:20:28 +06:00
c72dccc0f9 rework of stickers and stickersets 2022-08-13 11:58:42 +06:00
3fc1058491 start rework of stickers and stickersets 2022-08-13 00:02:48 +06:00
c3668e978b add support of custom emojis 2022-08-12 23:21:53 +06:00
5a4a6d5710 start 3.1.0 2022-08-12 22:42:47 +06:00
ed1d8beb2e Update libs.versions.toml 2022-08-12 13:28:45 +06:00
881ede7d2a start 3.0.3 2022-08-12 13:25:58 +06:00
60d3d279e7 Update gradle-wrapper.properties 2022-08-06 10:19:22 +06:00
4b84518dbb Merge pull request #637 from InsanusMokrassar/3.0.2
3.0.2
2022-08-06 00:40:46 +06:00
8b451791dd fixes 2022-08-06 00:39:46 +06:00
771fb5c288 Update build.gradle 2022-08-05 23:48:15 +06:00
d19ee74f8b Update CHANGELOG.md 2022-08-05 23:47:43 +06:00
aaf489c2ed Update gradle.properties 2022-08-05 23:47:06 +06:00
1b06b63703 update to hotfix up to 3.0.1 2022-08-05 22:49:32 +06:00
bf7fc25285 make lib dependency implementation instead of api 2022-08-05 22:30:11 +06:00
4df242747f fix dokka build 2022-08-05 22:03:10 +06:00
e831ca143e Merge pull request #634 from InsanusMokrassar/3.0.0
3.0.0
2022-08-05 21:54:31 +06:00
44838a2088 optimize imports in behaviour builder common 2022-08-05 21:44:36 +06:00
3823b03453 fixes 2022-08-05 21:43:15 +06:00
ec48708195 start to fill changelog 2022-08-05 21:27:45 +06:00
6a06775bc4 add file annotations generation to the class casts 2022-08-05 18:57:50 +06:00
bbdff0b31a rename file with new classcasts 2022-08-05 17:31:45 +06:00
cb4880bd00 optimize imports in utils 2022-08-05 16:35:07 +06:00
a18eda3db6 add generation of class casts 2022-08-05 16:31:39 +06:00
d8f6429385 solution for #636 2022-08-05 11:49:04 +06:00
be74249b67 Update README.md 2022-08-05 01:48:44 +06:00
69f658e4a8 rewrite hierarchy of forward info classes 2022-08-04 22:45:26 +06:00
8c51ca9d72 fixes in forward from public chat info 2022-08-04 22:27:40 +06:00
48c4a3156b fix of build 2022-08-04 18:15:51 +06:00
92407c9010 remove deprecations from copyMessage 2022-08-04 18:09:25 +06:00
86937cc096 remove deprecations 2022-08-04 18:01:35 +06:00
ea614b790b update serialization 2022-08-04 17:45:35 +06:00
c994332cb9 update dependencies 2022-08-04 17:18:05 +06:00
9d893ffa48 start 3.0.0 2022-08-04 17:12:34 +06:00
57d2fe85c5 Merge pull request #632 from InsanusMokrassar/2.2.2
2.2.2
2022-07-31 19:26:47 +06:00
c68b148d5e inline buildEntities 2022-07-31 18:26:07 +06:00
0a0a7cea0e fixes in callback query triggers 2022-07-31 17:49:48 +06:00
ea981605f6 start 0.2.2 2022-07-31 17:46:59 +06:00
fe1e65a83c Merge pull request #630 from InsanusMokrassar/2.2.1
2.2.1
2022-07-22 20:00:27 +06:00
c85983bd59 update microutils 2022-07-22 18:45:09 +06:00
d72e1029d3 fill changelog 2022-07-22 16:50:20 +06:00
4b89563cff fixes in classcasts, withContentOrNull and withContentOrThrow 2022-07-22 16:45:54 +06:00
542079f4bf Merge pull request #629 from d1snin/tgbotapi-627
Add content-oriented typealiases for messages
2022-07-22 16:15:02 +06:00
d1snin
5c7164e864 refactored the handlers to use new typealiases when possible 2022-07-18 11:59:01 +03:00
6329905f62 Update libs.versions.toml 2022-07-18 14:53:10 +06:00
c54945e4cc Update gradle-wrapper.properties 2022-07-18 14:52:16 +06:00
8f20e1d617 Update gradle.properties 2022-07-18 14:48:52 +06:00
d1snin
edbfedb74e added logically missing typealiases 2022-07-18 11:26:18 +03:00
d1snin
b5006cd1e0 Add content-oriented typealiases for messages 2022-07-18 11:02:13 +03:00
ca01ce7843 Merge pull request #628 from InsanusMokrassar/tg_channel_imh
Tg Channel QR
2022-07-18 13:44:04 +06:00
54fad3f338 Add files via upload 2022-07-18 13:43:06 +06:00
15ef481fd7 Update README.md 2022-07-18 13:42:17 +06:00
91e1202674 Delete 68a81ca4-7950-48df-b842-85f285ce3741.jpg 2022-07-18 13:33:23 +06:00
bdd39963a8 Add files via upload 2022-07-18 13:31:30 +06:00
01dfedf540 Merge pull request #623 from InsanusMokrassar/2.2.0
2.2.0
2022-07-11 11:18:07 +06:00
8ded892b72 new class casts 2022-07-11 02:20:28 +06:00
d0b606469b fixes related to owner chat member 2022-07-11 02:05:10 +06:00
678f79da04 CreatorChatMember -> OwnerChatMember 2022-07-11 01:56:31 +06:00
fde2c79f4c extract force_reply field into constant 2022-07-11 01:43:04 +06:00
acaf46e015 ReplyForce companion improvements 2022-07-11 01:27:28 +06:00
3f9237b5de flatInlineKeyboard and flatReplyKeyboard 2022-07-11 01:10:35 +06:00
3d7334dd62 sameChat 2022-07-11 00:57:13 +06:00
26306f1567 sameMessage 2022-07-11 00:53:20 +06:00
247553d990 add note about parameters order 2022-07-11 00:45:11 +06:00
049a8a3263 copy message order of parameters changed 2022-07-11 00:26:57 +06:00
cc67a31e97 start 2.2.0 2022-07-11 00:10:30 +06:00
8791573145 Update build.gradle 2022-07-10 00:04:36 +06:00
5752f7a4fb Merge pull request #622 from InsanusMokrassar/2.1.3
2.1.3
2022-07-09 23:54:18 +06:00
ade236eaa3 update microutils 2022-07-09 23:52:16 +06:00
e7340a483a fixes 2022-07-09 23:45:24 +06:00
c7dc69d09f ChatJoinRequest#inviteLink fix 2022-07-09 23:09:52 +06:00
c2487c5adc fixes in links 2022-07-09 22:43:19 +06:00
7c4808f163 start 2.1.3 2022-07-09 22:37:58 +06:00
b91b516659 Merge pull request #618 from InsanusMokrassar/2.1.2
2.1.2
2022-06-29 14:42:01 +06:00
57cdc4ff2a fill changelog 2022-06-29 14:27:29 +06:00
864992aff0 complete rewriting on libs.versions.toml 2022-06-29 14:23:45 +06:00
e18e8ba6df start to use more unified way of scripts organization 2022-06-29 13:47:21 +06:00
02cedc6626 start 2.1.2 2022-06-29 13:27:35 +06:00
619b890956 Merge pull request #615 from InsanusMokrassar/2.1.1
2.1.1
2022-06-26 13:42:26 +06:00
100a76a832 Update CHANGELOG.md 2022-06-26 13:36:13 +06:00
c583ae6761 replace all the edits into one file 2022-06-26 13:18:22 +06:00
7429ffb514 add TelegramBot#send extensions 2022-06-25 23:06:41 +06:00
95aeedfb94 Update DeleteMessage.kt 2022-06-25 18:34:41 +06:00
095e318a78 Update DeleteMessage.kt 2022-06-25 18:04:20 +06:00
4aa2d2ae41 Update gradle.properties 2022-06-25 03:13:46 +06:00
e936d25c13 TelegramBot#edit 2022-06-25 02:49:38 +06:00
97a2a5d9fd exists methods of editing text/caption improvements 2022-06-25 02:19:20 +06:00
00ab532eac start 2.1.1 2022-06-25 02:11:23 +06:00
c2cc6ee1ec Merge pull request #613 from InsanusMokrassar/2.1.0
2.1.0
2022-06-21 23:09:27 +06:00
d20b94e52c rename PremiumChat -> PossiblyPremiumChat 2022-06-21 23:06:36 +06:00
9f3cc6eafb add mention about 6.1 telegram bot api support 2022-06-21 18:58:01 +06:00
f86a095421 CreateInvoiceLink 2022-06-21 18:52:55 +06:00
b0c6b80d8b small improvements 2022-06-21 18:30:31 +06:00
1df653f428 SetWebhook#secretToken 2022-06-21 17:55:21 +06:00
8dfaca7648 CommonUser#addedToAttachmentMenu 2022-06-21 17:52:16 +06:00
04db76831f add support of premium fields 2022-06-21 17:34:14 +06:00
f2e9bf6bd8 update webapps support 2022-06-21 16:35:48 +06:00
cde8fdeffd start 2.1.0 2022-06-21 15:22:34 +06:00
e74f339ae2 Merge pull request #609 from InsanusMokrassar/2.0.3
2.0.3
2022-06-17 14:34:23 +06:00
ff7702486f downloadFileToTemp 2022-06-17 13:49:44 +06:00
c7818fe4df Update gradle.properties 2022-06-17 11:04:31 +06:00
8243acd69e regularln 2022-06-17 02:51:22 +06:00
8081602a39 update microutils 2022-06-17 00:20:30 +06:00
6fd85dbc56 start 2.0.3 2022-06-17 00:16:23 +06:00
8d6f4ba136 Merge pull request #602 from InsanusMokrassar/2.0.2
2.0.2
2022-06-05 21:01:10 +06:00
b95b339ad1 Update CHANGELOG.md 2022-06-05 17:40:53 +06:00
637979100b Update gradle.properties 2022-06-05 17:40:13 +06:00
4067439a13 update micro_utils 2022-06-04 21:01:40 +06:00
03583ff6c1 start 2.0.2 2022-06-04 21:00:33 +06:00
c1330f8e32 Merge pull request #598 from InsanusMokrassar/2.0.1
2.0.1
2022-05-29 23:06:15 +06:00
db36c6aacb Update CHANGELOG.md 2022-05-29 22:16:55 +06:00
757e317e70 Update gradle.properties 2022-05-29 22:15:56 +06:00
cb708a1ba4 Update CHANGELOG.md 2022-05-29 09:03:18 +06:00
551276f78e Update gradle.properties 2022-05-29 09:02:52 +06:00
88339a4977 Update CHANGELOG.md 2022-05-28 09:56:40 +06:00
a13371e14c Update gradle.properties 2022-05-28 09:55:10 +06:00
ad7fdc6211 improvements in longPolling extension 2022-05-22 22:36:56 +06:00
c870a48a22 start 2.0.1 2022-05-22 22:35:45 +06:00
3149fd0231 Merge pull request #597 from InsanusMokrassar/2.0.0
2.0.0
2022-05-22 12:58:46 +06:00
7430490499 fixes for build 2022-05-22 01:46:11 +06:00
416187e079 remove deprecations 2022-05-22 01:40:03 +06:00
e7aec75aca removing of filters for the wait triggers 2022-05-22 01:27:52 +06:00
95a466a08b start 2.0.0 2022-05-21 23:53:45 +06:00
507cb2af26 cleanup waiters in behaviour builder and add withEvent 2022-05-21 23:38:42 +06:00
126a07cdc7 start 1.2.0 2022-05-21 23:32:36 +06:00
27a24a18a6 fix of updates funnel in subsequent behaviour contexts 2022-05-21 21:44:33 +06:00
562e8c7429 improvements in Beheviour Context 2022-05-21 17:33:44 +06:00
be027efc43 start 1.1.4 2022-05-21 17:27:04 +06:00
e55195b308 Merge pull request #593 from InsanusMokrassar/1.1.3
1.1.3
2022-05-19 13:38:05 -04:00
14afb59b5f StateHandlingErrorHandler in microutils 2022-05-19 20:37:52 +06:00
6b23347d56 start 1.1.3 2022-05-19 20:24:55 +06:00
f54843fb60 Merge pull request #592 from InsanusMokrassar/1.1.2
1.1.2
2022-05-18 07:10:31 -04:00
8a3538d9c7 fixes in relate to main behaviourBuilder fun 2022-05-18 17:05:47 +06:00
e3db4250bb add default copy realization in BehaviourContextWithFSM 2022-05-18 16:52:52 +06:00
4643ac906a StateHandlingErrorHandler 2022-05-18 16:45:08 +06:00
497974e45c fix of #591 2022-05-18 16:31:14 +06:00
78a00f0efb start 1.1.2 2022-05-18 16:27:30 +06:00
14ecb9d948 Merge pull request #590 from InsanusMokrassar/1.1.1
1.1.1
2022-05-17 09:56:47 -04:00
322 changed files with 11882 additions and 4937 deletions

View File

@@ -1,5 +1,170 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 3.1.0
**This update contains including of Bot API 6.2**
* `Versions`:
* `Ktor`: `2.0.3` -> `2.1.0`
* `MicroUtils`: `0.12.0` -> `0.12.1`
* `Core`:
* Add support of `custom emoji`s
* Add support of `sticker_type`
## 3.0.2
**ALL OLD DEPRECATIONS HAVE BEEN REMOVED**
**`copyMessage` HAVE CHANGED THEIR SIGNATURE BY SWAPPING FROM AND TO CHAT IDS**
* `Versions`:
* `Kotlin`: `1.6.21` -> `1.7.10`
* `Serialization`: `1.3.3` -> `1.4.0-RC`
* `Korlibs`: `2.7.0` -> `3.0.0`
* `UUID`: `0.4.1` -> `0.5.0`
* `MicroUtils`: `0.11.13` -> `0.12.0`
* `Core`:
* Interface `ReplyMakrup` has been renamed to `WithReplyMarkup` to correspond its purpose
* Data class `LeftChatMember` has been renamed to `LeftChatMemberEvent` to avoid type ambiguite with the other `LeftChatMember`
* `ForwardInfo` hierarchy has been fully reworked:
* `AnonymousForwardInfo` -> `ForwardInfo.ByAnonymous`
* `UserForwardInfo` -> `ForwardInfo.ByUser`
* `ForwardFromPublicChatInfo` -> `ForwardInfo.PublicChat`
* `ForwardFromChannelInfo` -> `ForwardInfo.PublicChat.FromChannel`
* `ForwardFromSupergroupInfo` -> `ForwardInfo.PublicChat.FromSupergroup`
* `ForwardInfo.PublicChat.SentByChannel` ___has been created___
* `API`:
* Add new `Flow`-based live locations API
* Add `sendLocation` for sending live locations
* `Utils`:
* **BREAKING CHANGES** Now all new classcasts (like `Chat.ifPrivateChat` etc.) have been rewritten to be generated with `ksp` and `kotlin poet`
*Note: Versions 3.0.0 and 3.0.1 have been published with errors and didn't recommend to use*
## 2.2.2
* `Utils`:
* `buildEntities` now is inline
* `Behaviour Builder`:
* Fixes in `CallbackQuery` triggers
## 2.2.1
* `Versions`:
* `Coroutines`: `1.6.3` -> `1.6.4`
* `MicroUtils`: `0.11.12` -> `0.11.13`
* `Core`:
* New `typealiase`s for `CommonMessage` with all supported content types, more info: [PR](https://github.com/InsanusMokrassar/TelegramBotAPI/pull/629)
* `Utils`:
* New extensions for all types of messages `*.withContentOrNull` and `*.withContentOrThrow` as analogies to the same ones from class casts
## 2.2.0
* `Core`:
* For `CopyMessage` order of parameters has been changed
* `ReplyForce` defaults changes:
* All old companion properties (like `ReplyForce.ReplyForceSelective`) have been renamed:
* `ReplyForceSelective` -> `Selective`
* `ReplyForceNonSelective` -> `NonSelective`
* `ReplyForceDefault` -> `Default`
* New companion functions:
* `ReplyForce#Selective`
* `ReplyForce#NonSelective`
* Rename `CreatorChatMember` -> `OwnerChatMember`
* `API`:
* For `copyMessage` order of parameters has been changed
* `Utils`:
* New extension `Message#sameChat`
* New extension `Message#sameMessage`
* New functions `flatInlineKeyboard` and `flatReplyKeyboard`
* Experimentally add new triple of class casts: `if*`, `*OrNull` and `*OrThrow`
## 2.1.3
* `Versions`:
* `MicroUtils`: `0.11.9` -> `0.11.12`
* `Utils`:
* Rename `UserId` extension `link` to `userLink`
* `Core`
* `ChatJoinRequest#inviteLink` is nullable due to the fact that join requests without link do not require invite link
## 2.1.2
* `Versions`:
* `Coroutines`: `1.6.1` -> `1.6.3`
* `Ktor`: `2.0.2` -> `2.0.3`
* `MicroUtils`: `0.11.6` -> `0.11.9`
## 2.1.1
* `API`:
* Now it is possible to edit any message text via `editMessageText` (but with warning)
* Now it is possible to edit any message caption via `editMessageCaption` (but with warning)
* Media message caption edit method (`editMessageCaption`) now returns the message with the same generic type (as it must be in telegram system)
* New extensions `TelegramBot#edit` has been added for all possible editions types
* New extensions `TelegramBot#send` has been added for all possible sending types
* New extensions `TelegramBot#delete` has been added
* `Versions`:
* `MicroUtils`: `0.11.3` -> `0.11.6`
## 2.1.0
__This update contains including of [Telegram Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022)__
* Add support of functionality for `WebApp`s from [Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022)
* Add support of functionality for premium feature from [Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022)
* Add support of `addedToAttachmentMenu` in `CommonUser` from [Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022)
* Add support of `secret_token` in `SetWebhook` request from [Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022)
* Add support of `createInvoiceLink` request from [Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022)
## 2.0.3
* `Core`:
* New function `regularln` for simple creating of `RegularTextSource` with new line in the end
* `API`:
* New function `downloadFileToTemp` for simple downloading of file in filesystem and manipulation with avoiding of direct using input streams and other low-level things
* `Versions`:
* `MicroUtils`: `0.11.0` -> `0.11.3`
## 2.0.2
* `Versions`:
* `MicroUtils`: `0.10.8` -> `0.11.0`
* `UUID`: `0.4.0` -> `0.4.1`
## 2.0.1
* `Versions`:
* `Ktor`: `2.0.1` -> `2.0.2`
* `MicroUtils`: `0.10.5` -> `0.10.8`
* `Utils`:
* `TelegramBot#longPolling` now accepts `UpdatesFilter` instead of `FlowsUpdatesFilter`
## 2.0.0
___ALL PREVIOUS DEPRECATIONS HAVE BEEN REMOVED___
* `Behaviour Builder`:
* Mappers have been removed from waiters extensions
* Triggers extensions now will use filtering inside of context receiver instead of passing the filters into `BehaviourContext`. That means that in the subcontext will not be used preinstalled filters for their `BehaviourContext` and filter of trigger will not be used in subcontext
* Waiters do not take count parameter anymore
* Waiters do not take filter parameter anymore. Use flows filters
* `Utils`:
* Add opportunity to get event messages with specific `ChatEvent` type using `withEvent`/`requireWithEvent` (by analog with `withEvent` and `requireWithEvent`)
## 1.1.3
* `Behaviour Builder with FSM`:
* Typealias `StateHandlingErrorHandler` from `1.1.2` has been deprecated and should be replaced with the new one from microutils
## 1.1.2
* `Core`:
* Rename of `TelegramAPIUrlsKeeper#checkWebAppLink` -> `TelegramAPIUrlsKeeper#checkWebAppData` (fix of [#591](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/591))
* `Behaviour Builder with FSM`:
* New typealias `StateHandlingErrorHandler`
* `BehaviourBuilderWithFSM` now accepts new parameter `onStateHandlingErrorHandler` which will be used in case if state has not been successfully completed
## 1.1.1 ## 1.1.1
* `Versions`: * `Versions`:

View File

@@ -1,8 +1,17 @@
# 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.0-blue)](https://core.telegram.org/bots/api-changelog#april-16-2022) # 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.2-blue)](https://core.telegram.org/bots/api-changelog#august-12-2022)
| [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://github.com/InsanusMokrassar/TelegramBotAPI/workflows/Build/badge.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [![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) [![Chat in Telegram](https://img.shields.io/static/v1?label=Telegram&message=Chat&color=blue&logo=telegram)](https://t.me/InMoTelegramBotAPI) | | 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) |
|:---:| |:---:|:---:|
| [![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/) [![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) | | 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) |
<!--- [![Telegram Channel](./resources/tg_channel_qr.jpg)](https://t.me/InMoTelegramBotAPI) --->
<p align="center">
<a href="https://t.me/InMoTelegramBotAPI">
<img src="./resources/tg_channel_qr.jpg">
</a>
</p>
Hello! This is a set of libraries for working with Telegram Bot API. Hello! This is a set of libraries for working with Telegram Bot API.

View File

@@ -6,19 +6,21 @@ buildscript {
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath libs.kotlin.gradle.plugin
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" classpath libs.kotlin.ksp.plugin
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version" classpath libs.kotlin.serialization.plugin
classpath libs.kotlin.dokka.plugin
classpath libs.github.release.plugin
} }
} }
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" apply false
}
// 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
allprojects { allprojects {
repositories {
mavenLocal()
mavenCentral()
google()
}
if (it != rootProject.findProject("docs")) { if (it != rootProject.findProject("docs")) {
tasks.whenTaskAdded { task -> tasks.whenTaskAdded { task ->
if(task.name == "jsLegacyBrowserTest" || task.name == "jsLegacyNodeTest") { if(task.name == "jsLegacyBrowserTest" || task.name == "jsLegacyNodeTest") {
@@ -27,6 +29,7 @@ allprojects {
} }
} }
} }
apply from: "./extensions.gradle"
private String getCurrentVersionChangelog() { private String getCurrentVersionChangelog() {
OutputStream changelogDataOS = new ByteArrayOutputStream() OutputStream changelogDataOS = new ByteArrayOutputStream()
@@ -48,7 +51,7 @@ if (new File(projectDir, "secret.gradle").exists()) {
owner "InsanusMokrassar" owner "InsanusMokrassar"
repo "TelegramBotAPI" repo "TelegramBotAPI"
tagName "$library_version" tagName "v$library_version"
releaseName "$library_version" releaseName "$library_version"
targetCommitish "$library_version" targetCommitish "$library_version"

View File

@@ -1,45 +1,17 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
}
}
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "org.jetbrains.dokka" version "$dokka_version" id "org.jetbrains.dokka"
} }
repositories { project.description = "Full collection of all built-in tgbotapi tools"
mavenLocal()
mavenCentral() apply from: "$mppProjectWithSerializationPresetPath"
}
kotlin { kotlin {
jvm {
compilations.main {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js(IR) {
browser()
nodejs()
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib')
api project(":tgbotapi.core") api project(":tgbotapi.core")
api project(":tgbotapi.api") api project(":tgbotapi.api")
api project(":tgbotapi.utils") api project(":tgbotapi.utils")
@@ -58,12 +30,13 @@ kotlin {
private List<SourceDirectorySet> findSourcesWithName(String... approximateNames) { private List<SourceDirectorySet> findSourcesWithName(String... approximateNames) {
return parent.subprojects return parent.subprojects
.findAll { it != project } .findAll { it != project && it.hasProperty("kotlin") }
.collectMany { it.kotlin.sourceSets } .collectMany { it.kotlin.sourceSets }
.findAll { sourceSet -> approximateNames.any { .findAll { sourceSet ->
nameToFilter -> sourceSet.name.contains(nameToFilter) approximateNames.any { nameToFilter ->
} sourceSet.name.contains(nameToFilter)
}.collect { it.kotlin } }
}.collect { it.kotlin }
} }
Object callback = { Object callback = {
@@ -103,8 +76,3 @@ Object callback = {
tasks.dokkaGfm(callback) tasks.dokkaGfm(callback)
tasks.dokkaHtml(callback) tasks.dokkaHtml(callback)
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

8
extensions.gradle Normal file
View File

@@ -0,0 +1,8 @@
allprojects {
ext {
mppProjectWithSerializationPresetPath = "${rootProject.projectDir.absolutePath}/mppProjectWithSerialization.gradle"
mppJsProjectPresetPath = "${rootProject.projectDir.absolutePath}/mppJsProject.gradle"
publishGradlePath = "${rootProject.projectDir.absolutePath}/publish.gradle"
}
}

View File

@@ -5,21 +5,5 @@ kotlin.js.generate.externals=true
kotlin.incremental=true kotlin.incremental=true
kotlin.incremental.js=true kotlin.incremental.js=true
kotlin_version=1.6.21
kotlin_coroutines_version=1.6.1
kotlin_serialisation_runtime_version=1.3.3
korlibs_version=2.7.0
uuid_version=0.4.0
ktor_version=2.0.1
micro_utils_version=0.10.4
javax_activation_version=1.1.1
dokka_version=1.6.21
library_group=dev.inmo library_group=dev.inmo
library_version=1.1.1 library_version=3.1.0
github_release_plugin_version=2.3.7

68
gradle/libs.versions.toml Normal file
View File

@@ -0,0 +1,68 @@
[versions]
kotlin = "1.7.10"
kotlin-serialization = "1.4.0-RC"
kotlin-coroutines = "1.6.4"
javax-activation = "1.1.1"
korlibs = "3.0.0"
uuid = "0.5.0"
ktor = "2.1.0"
ksp = "1.7.10-1.0.6"
kotlin-poet = "1.12.0"
microutils = "0.12.1"
github-release-plugin = "2.4.1"
[libraries]
kotlin = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization" }
kotlin-serialization-properties = { module = "org.jetbrains.kotlinx:kotlinx-serialization-properties", version.ref = "kotlin-serialization" }
kotlin-test-common = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "kotlin" }
kotlin-test-annotations-common = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlin" }
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
kotlin-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = "kotlin" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-server = { module = "io.ktor:ktor-server", version.ref = "ktor" }
ktor-server-host-common = { module = "io.ktor:ktor-server-host-common", version.ref = "ktor" }
javax-activation = { module = "javax.activation:activation", version.ref = "javax-activation" }
korlibs-klock = { module = "com.soywiz.korlibs.klock:klock", version.ref = "korlibs" }
korlibs-krypto = { module = "com.soywiz.korlibs.krypto:krypto", version.ref = "korlibs" }
uuid = { module = "com.benasher44:uuid", version.ref = "uuid" }
microutils-coroutines = { module = "dev.inmo:micro_utils.coroutines", version.ref = "microutils" }
microutils-serialization-base64 = { module = "dev.inmo:micro_utils.serialization.base64", version.ref = "microutils" }
microutils-serialization-encapsulator = { module = "dev.inmo:micro_utils.serialization.encapsulator", version.ref = "microutils" }
microutils-serialization-typedSerializer = { module = "dev.inmo:micro_utils.serialization.typed_serializer", version.ref = "microutils" }
microutils-languageCodes = { module = "dev.inmo:micro_utils.language_codes", 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" }
# ksp dependencies
kotlin-poet = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin-poet" }
ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
# buildscript classpaths
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-ksp-plugin = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" }
kotlin-serialization-plugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
kotlin-dokka-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "kotlin" }
github-release-plugin = { module = "com.github.breadmoirai:github-release", version.ref = "github-release-plugin" }
[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }

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

32
mppJsProject.gradle Normal file
View File

@@ -0,0 +1,32 @@
project.version = "$version"
project.group = "$group"
apply from: "$publishGradlePath"
kotlin {
js (IR) {
browser()
nodejs()
}
sourceSets {
commonMain {
dependencies {
implementation libs.kotlin
api libs.kotlin.serialization
}
}
commonTest {
dependencies {
implementation libs.kotlin.test.common
implementation libs.kotlin.test.annotations.common
}
}
jsTest {
dependencies {
implementation libs.kotlin.test.js
implementation libs.kotlin.test.junit
}
}
}
}

View File

@@ -0,0 +1,47 @@
project.version = "$library_version"
project.group = "$library_group"
kotlin {
jvm {
compilations.main {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js (IR) {
browser()
nodejs()
}
sourceSets {
commonMain {
dependencies {
implementation libs.kotlin
api libs.kotlin.serialization
}
}
commonTest {
dependencies {
implementation libs.kotlin.test.common
implementation libs.kotlin.test.annotations.common
}
}
jvmTest {
dependencies {
implementation libs.kotlin.test.junit
}
}
jsTest {
dependencies {
implementation libs.kotlin.test.js
implementation libs.kotlin.test.junit
}
}
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

BIN
resources/tg_channel_qr.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

View File

@@ -12,6 +12,7 @@ pluginManagement {
} }
include ":tgbotapi.core" include ":tgbotapi.core"
include ":tgbotapi.ksp"
include ":tgbotapi.api" include ":tgbotapi.api"
include ":tgbotapi.utils" include ":tgbotapi.utils"
include ":tgbotapi.behaviour_builder" include ":tgbotapi.behaviour_builder"

View File

@@ -1,56 +1,20 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
} }
project.version = "$library_version"
project.group = "$library_group"
project.description = "API extensions with \"Telegram Bot API\"-like extensions for TelegramBot and RequestsExecutor" project.description = "API extensions with \"Telegram Bot API\"-like extensions for TelegramBot and RequestsExecutor"
apply from: "../publish.gradle" apply from: "$mppProjectWithSerializationPresetPath"
apply from: "$publishGradlePath"
repositories {
mavenLocal()
mavenCentral()
}
kotlin { kotlin {
jvm {
compilations.main {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js(IR) {
browser()
nodejs()
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib')
api project(":tgbotapi.core") api project(":tgbotapi.core")
} }
} }
} }
} }
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@@ -23,6 +23,20 @@ suspend fun TelegramBot.deleteMessage(
message: Message message: Message
) = deleteMessage(message.chat, message.messageId) ) = deleteMessage(message.chat, message.messageId)
suspend fun TelegramBot.delete(
chatId: ChatIdentifier,
messageId: MessageIdentifier
) = deleteMessage(chatId, messageId)
suspend fun TelegramBot.delete(
chat: Chat,
messageId: MessageIdentifier
) = deleteMessage(chat, messageId)
suspend fun TelegramBot.delete(
message: Message
) = deleteMessage(message)
suspend fun Message.delete( suspend fun Message.delete(
requestsExecutor: TelegramBot requestsExecutor: TelegramBot
) = requestsExecutor.deleteMessage(this) ) = requestsExecutor.deleteMessage(this)

View File

@@ -0,0 +1,151 @@
package dev.inmo.tgbotapi.extensions.api
import dev.inmo.micro_utils.coroutines.LinkedSupervisorJob
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.abstracts.*
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
import dev.inmo.tgbotapi.extensions.api.send.sendLiveLocation
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.location.LiveLocation
import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LocationContent
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.Serializable
import kotlin.js.JsName
import kotlin.jvm.JvmName
import kotlin.math.ceil
@Serializable
data class EditLiveLocationInfo(
override val latitude: Double,
override val longitude: Double,
override val horizontalAccuracy: Meters? = null,
override val heading: Degrees? = null,
override val proximityAlertRadius: Meters? = null,
override val replyMarkup: InlineKeyboardMarkup? = null
) : Locationed, HorizontallyAccured, ProximityAlertable, Headed, WithReplyMarkup
/**
* Will [sendLiveLocation] with the first [EditLiveLocationInfo] data and update than. Each [liveTimeMillis] passing,
* the message will be sent again and new edits will be applied to the new message
*/
suspend fun TelegramBot.handleLiveLocation(
chatId: ChatIdentifier,
locationsFlow: Flow<EditLiveLocationInfo>,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
) {
var currentLiveLocationMessage: ContentMessage<LocationContent>? = null
val updateMessageJob = CoroutineScope(currentCoroutineContext().LinkedSupervisorJob()).launchSafelyWithoutExceptions(start = CoroutineStart.LAZY) {
while (isActive) {
delay(liveTimeMillis)
// Remove previous location message info to resend live location message
currentLiveLocationMessage = null
}
}
locationsFlow.collect {
val capturedLiveLocationMessage = currentLiveLocationMessage
if (capturedLiveLocationMessage == null) {
updateMessageJob.start()
currentLiveLocationMessage = sendLiveLocation(
chatId,
it.latitude,
it.longitude,
ceil(liveTimeMillis.toDouble() / 1000).toInt(),
it.horizontalAccuracy,
it.heading,
it.proximityAlertRadius,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
it.replyMarkup
)
} else {
editLiveLocation(
capturedLiveLocationMessage,
it.latitude,
it.longitude,
it.horizontalAccuracy,
it.heading,
it.proximityAlertRadius,
it.replyMarkup
)
}
}
}
/**
* Will apply [Flow.map] to the [locationsFlow] to create [EditLiveLocationInfo] and pass the result flow to the
* [handleLiveLocation] with [Flow] typed by [EditLiveLocationInfo]
*/
@JvmName("handleLiveLocationWithLocation")
@JsName("handleLiveLocationWithLocation")
suspend fun TelegramBot.handleLiveLocation(
chatId: ChatIdentifier,
locationsFlow: Flow<Location>,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
) {
handleLiveLocation(
chatId,
locationsFlow.map {
EditLiveLocationInfo(
it.latitude,
it.longitude,
it.horizontalAccuracy,
(it as? LiveLocation) ?.heading,
(it as? LiveLocation) ?.proximityAlertRadius,
(it as? WithReplyMarkup) ?.replyMarkup as? InlineKeyboardMarkup
)
},
liveTimeMillis,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply
)
}
/**
* Will apply [Flow.map] to the [locationsFlow] to create [EditLiveLocationInfo] and pass the result flow to the
* [handleLiveLocation] with [Flow] typed by [EditLiveLocationInfo]
*/
@JvmName("handleLiveLocationWithLatLong")
@JsName("handleLiveLocationWithLatLong")
suspend fun TelegramBot.handleLiveLocation(
chatId: ChatIdentifier,
locationsFlow: Flow<Pair<Double, Double>>,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null
) {
handleLiveLocation(
chatId,
locationsFlow.map { (lat, long) ->
EditLiveLocationInfo(
lat,
long
)
},
liveTimeMillis,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply
)
}

View File

@@ -0,0 +1,207 @@
package dev.inmo.tgbotapi.extensions.api.edit
import dev.inmo.tgbotapi.abstracts.TextedWithTextSources
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.caption.editMessageCaption
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
import dev.inmo.tgbotapi.extensions.api.edit.media.editMessageMedia
import dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup
import dev.inmo.tgbotapi.extensions.api.edit.text.editMessageText
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.location.LiveLocation
import dev.inmo.tgbotapi.types.media.TelegramMedia
import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun <T> TelegramBot.edit(
message: ContentMessage<T>,
text: String,
parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<T> where T : TextedWithTextSources, T : MediaContent {
return editMessageCaption(message, text, parseMode, replyMarkup)
}
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun <T> TelegramBot.edit(
message: ContentMessage<T>,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<T> where T : TextedWithTextSources, T : MediaContent {
return editMessageCaption(message, entities, replyMarkup)
}
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chatId, messageId, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chat: Chat,
messageId: MessageIdentifier,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chat, messageId, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
message: ContentMessage<LocationContent>,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(message, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(
chatId, messageId, location, replyMarkup
)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chat: Chat,
messageId: MessageIdentifier,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chat, messageId, location, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
message: ContentMessage<LocationContent>,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(message, location, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
media: TelegramMedia,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageMedia(chatId, messageId, media, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chat: Chat,
messageId: MessageIdentifier,
media: TelegramMedia,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageMedia(chat, messageId, media, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
message: ContentMessage<MediaContent>,
media: TelegramMedia,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageMedia(message, media, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(chatId, messageId, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
chat: Chat,
messageId: MessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(chat, messageId, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
message: Message,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(message, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
message: ContentMessage<TextContent>,
text: String,
parseMode: ParseMode? = null,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageText(message, text, parseMode, disableWebPagePreview, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun TelegramBot.edit(
message: ContentMessage<TextContent>,
entities: TextSourcesList,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageText(message, entities, disableWebPagePreview, replyMarkup)

View File

@@ -1,92 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.edit.LiveLocation
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.location.LiveLocation
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chatId, messageId, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
chat: Chat,
messageId: MessageIdentifier,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chat, messageId, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
message: ContentMessage<LocationContent>,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(message, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chatId, messageId, location, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
chat: Chat,
messageId: MessageIdentifier,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chat, messageId, location, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
message: ContentMessage<LocationContent>,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(message, location, replyMarkup)

View File

@@ -1,25 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.edit.LiveLocation
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
import dev.inmo.tgbotapi.requests.edit.location.live.EditInlineMessageLiveLocation
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.location.LiveLocation
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
inlineMessageId: InlineMessageIdentifier,
latitude: Double,
longitude: Double,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(inlineMessageId, latitude, longitude, horizontalAccuracy, heading, proximityAlertRadius, replyMarkup)
@Deprecated("Replaced", ReplaceWith("editLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation"))
suspend fun TelegramBot.editLiveLocation(
inlineMessageId: InlineMessageIdentifier,
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(inlineMessageId, location, replyMarkup)

View File

@@ -1,43 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.edit.LiveLocation
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation
import dev.inmo.tgbotapi.requests.edit.location.live.StopChatMessageLiveLocation
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LocationContent
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("stopLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation"))
suspend fun TelegramBot.stopLiveLocation(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = stopLiveLocation(chatId, messageId, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("stopLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation"))
suspend fun TelegramBot.stopLiveLocation(
chat: Chat,
messageId: MessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = stopLiveLocation(chat, messageId, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("stopLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation"))
suspend fun TelegramBot.stopLiveLocation(
message: ContentMessage<LocationContent>,
replyMarkup: InlineKeyboardMarkup? = null
) = stopLiveLocation(message, replyMarkup)

View File

@@ -1,17 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.edit.LiveLocation
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation
import dev.inmo.tgbotapi.requests.edit.location.live.StopInlineMessageLiveLocation
import dev.inmo.tgbotapi.types.InlineMessageIdentifier
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("stopLiveLocation", "dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation"))
suspend fun TelegramBot.stopLiveLocation(
inlineMessageId: InlineMessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = stopLiveLocation(inlineMessageId, replyMarkup)

View File

@@ -1,42 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.edit.ReplyMarkup
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.message.abstracts.Message
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editMessageReplyMarkup", "dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup"))
suspend fun TelegramBot.editMessageReplyMarkup(
chatId: ChatIdentifier,
messageId: MessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(chatId, messageId, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editMessageReplyMarkup", "dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup"))
suspend fun TelegramBot.editMessageReplyMarkup(
chat: Chat,
messageId: MessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(chat, messageId, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editMessageReplyMarkup", "dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup"))
suspend fun TelegramBot.editMessageReplyMarkup(
message: Message,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(message, replyMarkup)

View File

@@ -1,17 +0,0 @@
package dev.inmo.tgbotapi.extensions.api.edit.ReplyMarkup
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup
import dev.inmo.tgbotapi.requests.edit.reply_markup.EditInlineMessageReplyMarkup
import dev.inmo.tgbotapi.types.InlineMessageIdentifier
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Replaced", ReplaceWith("editMessageReplyMarkup", "dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup"))
suspend fun TelegramBot.editMessageReplyMarkup(
inlineMessageId: InlineMessageIdentifier,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageReplyMarkup(inlineMessageId, replyMarkup)

View File

@@ -11,7 +11,9 @@ import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.MediaContent import dev.inmo.tgbotapi.types.message.content.MediaContent
import dev.inmo.tgbotapi.utils.RiskFeature
/** /**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] * @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
@@ -48,8 +50,9 @@ suspend fun <T> TelegramBot.editMessageCaption(
text: String, text: String,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<MediaContent> where T : TextedWithTextSources, T : MediaContent { ): ContentMessage<T> where T : TextedWithTextSources, T : MediaContent {
return editMessageCaption(message.chat.id, message.messageId, text, parseMode, replyMarkup) @Suppress("UNCHECKED_CAST")
return editMessageCaption(message.chat.id, message.messageId, text, parseMode, replyMarkup) as ContentMessage<T>
} }
/** /**
@@ -84,6 +87,20 @@ suspend fun <T> TelegramBot.editMessageCaption(
message: ContentMessage<T>, message: ContentMessage<T>,
entities: List<TextSource>, entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<T> where T : TextedWithTextSources, T : MediaContent {
@Suppress("UNCHECKED_CAST")
return editMessageCaption(message.chat.id, message.messageId, entities, replyMarkup) as ContentMessage<T>
}
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@RiskFeature("This method is unsafe due to absence of any guaranties about the type of message. In case if message is not media message this method will throw an exception")
suspend fun <T> TelegramBot.editMessageCaption(
message: Message,
entities: List<TextSource>,
replyMarkup: InlineKeyboardMarkup? = null
): ContentMessage<MediaContent> where T : TextedWithTextSources, T : MediaContent { ): ContentMessage<MediaContent> where T : TextedWithTextSources, T : MediaContent {
return editMessageCaption(message.chat.id, message.messageId, entities, replyMarkup) return editMessageCaption(message.chat.id, message.messageId, entities, replyMarkup)
} }

View File

@@ -9,7 +9,9 @@ import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.utils.RiskFeature
/** /**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] * @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
@@ -87,3 +89,15 @@ suspend fun TelegramBot.editMessageText(
disableWebPagePreview: Boolean? = null, disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
) = editMessageText(message.chat.id, message.messageId, entities, disableWebPagePreview, replyMarkup) ) = editMessageText(message.chat.id, message.messageId, entities, disableWebPagePreview, replyMarkup)
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@RiskFeature("This method is unsafe due to absence of any guaranties about the type of message. In case if message is not text message this method will throw an exception")
suspend fun TelegramBot.editMessageText(
message: Message,
entities: TextSourcesList,
disableWebPagePreview: Boolean? = null,
replyMarkup: InlineKeyboardMarkup? = null
) = editMessageText(message.chat.id, message.messageId, entities, disableWebPagePreview, replyMarkup)

View File

@@ -0,0 +1,37 @@
package dev.inmo.tgbotapi.extensions.api.get
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.get.GetCustomEmojiStickers
import dev.inmo.tgbotapi.requests.get.GetStickerSet
import dev.inmo.tgbotapi.types.CustomEmojiId
import dev.inmo.tgbotapi.types.files.Sticker
import kotlin.js.JsName
import kotlin.jvm.JvmName
suspend fun TelegramBot.getCustomEmojiStickers(
customEmojiIds: List<CustomEmojiId>
) = execute(
GetCustomEmojiStickers(customEmojiIds)
)
@JvmName("getCustomEmojiStickersWithStringsList")
@JsName("getCustomEmojiStickersWithStringsList")
suspend fun TelegramBot.getCustomEmojiStickers(
customEmojiIds: List<String>
) = getCustomEmojiStickers(customEmojiIds.map(::CustomEmojiId))
suspend fun TelegramBot.getCustomEmojiStickerOrNull(
customEmojiId: CustomEmojiId
) = getCustomEmojiStickers(listOf(customEmojiId)).firstOrNull()
suspend fun TelegramBot.getCustomEmojiStickerOrThrow(
customEmojiId: CustomEmojiId
) = getCustomEmojiStickers(listOf(customEmojiId)).first()
suspend fun TelegramBot.getCustomEmojiStickerOrNull(
customEmojiId: String
) = getCustomEmojiStickerOrNull(CustomEmojiId(customEmojiId))
suspend fun TelegramBot.getCustomEmojiStickerOrThrow(
customEmojiId: String
) = getCustomEmojiStickerOrThrow(CustomEmojiId(customEmojiId))

View File

@@ -16,7 +16,227 @@ import dev.inmo.tgbotapi.types.message.abstracts.Message
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
fromChatId: ChatIdentifier, fromChatId: ChatIdentifier,
messageId: MessageIdentifier,
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = execute(
CopyMessage(
fromChatId,
messageId,
toChatId,
text,
parseMode,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChat: Chat,
messageId: MessageIdentifier,
toChatId: ChatIdentifier,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, messageId, toChatId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChatId: ChatIdentifier,
messageId: MessageIdentifier,
toChat: Chat,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChatId, messageId, toChat.id, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChat: Chat,
messageId: MessageIdentifier,
toChat: Chat,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, messageId, toChat.id, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChatId: ChatIdentifier,
messageId: MessageIdentifier,
toChatId: ChatIdentifier,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = execute(
CopyMessage(
fromChatId,
messageId,
toChatId,
entities,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChat: Chat,
messageId: MessageIdentifier,
toChatId: ChatIdentifier,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, messageId, toChatId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChatId: ChatIdentifier,
messageId: MessageIdentifier,
toChat: Chat,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChatId, messageId, toChat.id, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChat: Chat,
messageId: MessageIdentifier,
toChat: Chat,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, messageId, toChat.id, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChatId: ChatIdentifier,
message: Message,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, message.messageId, toChatId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
message: Message,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, message.messageId, toChat, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChatId: ChatIdentifier,
message: Message,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, message.messageId, toChatId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
message: Message,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, message.messageId, toChat, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChatId: ChatIdentifier,
fromChatId: ChatIdentifier,
messageId: MessageIdentifier, messageId: MessageIdentifier,
text: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
@@ -26,7 +246,18 @@ suspend inline fun TelegramBot.copyMessage(
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = execute( ) = execute(
CopyMessage(fromChatId, toChatId, messageId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) CopyMessage(
fromChatId,
messageId,
toChatId,
text,
parseMode,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
) )
/** /**
@@ -34,8 +265,8 @@ suspend inline fun TelegramBot.copyMessage(
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param * [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
toChatId: ChatIdentifier,
fromChat: Chat, fromChat: Chat,
toChatId: ChatIdentifier,
messageId: MessageIdentifier, messageId: MessageIdentifier,
text: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
@@ -44,15 +275,26 @@ suspend inline fun TelegramBot.copyMessage(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, toChatId, messageId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
toChatId,
fromChat.id,
messageId,
text,
parseMode,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/** /**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or * @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param * [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
fromChatId: ChatIdentifier,
toChat: Chat, toChat: Chat,
fromChatId: ChatIdentifier,
messageId: MessageIdentifier, messageId: MessageIdentifier,
text: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
@@ -61,15 +303,26 @@ suspend inline fun TelegramBot.copyMessage(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChatId, toChat.id, messageId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
toChat.id,
fromChatId,
messageId,
text,
parseMode,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/** /**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or * @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param * [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
fromChat: Chat, fromChat: Chat,
toChat: Chat,
messageId: MessageIdentifier, messageId: MessageIdentifier,
text: String? = null, text: String? = null,
parseMode: ParseMode? = null, parseMode: ParseMode? = null,
@@ -78,7 +331,19 @@ suspend inline fun TelegramBot.copyMessage(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, toChat.id, messageId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
toChat.id,
fromChat.id,
messageId,
text,
parseMode,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/** /**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or * @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
@@ -86,40 +351,7 @@ suspend inline fun TelegramBot.copyMessage(
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
message: Message,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, toChatId, message.messageId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
message: Message,
text: String? = null,
parseMode: ParseMode? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, toChat, message.messageId, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
fromChatId: ChatIdentifier, fromChatId: ChatIdentifier,
toChatId: ChatIdentifier,
messageId: MessageIdentifier, messageId: MessageIdentifier,
entities: TextSourcesList, entities: TextSourcesList,
disableNotification: Boolean = false, disableNotification: Boolean = false,
@@ -128,7 +360,17 @@ suspend inline fun TelegramBot.copyMessage(
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = execute( ) = execute(
CopyMessage(fromChatId, toChatId, messageId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) CopyMessage(
fromChatId,
messageId,
toChatId,
entities,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
) )
/** /**
@@ -136,8 +378,8 @@ suspend inline fun TelegramBot.copyMessage(
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param * [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
fromChat: Chat,
toChatId: ChatIdentifier, toChatId: ChatIdentifier,
fromChat: Chat,
messageId: MessageIdentifier, messageId: MessageIdentifier,
entities: TextSourcesList, entities: TextSourcesList,
disableNotification: Boolean = false, disableNotification: Boolean = false,
@@ -145,15 +387,25 @@ suspend inline fun TelegramBot.copyMessage(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, toChatId, messageId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
toChatId,
fromChat.id,
messageId,
entities,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/** /**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or * @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param * [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
fromChatId: ChatIdentifier, fromChatId: ChatIdentifier,
toChat: Chat,
messageId: MessageIdentifier, messageId: MessageIdentifier,
entities: TextSourcesList, entities: TextSourcesList,
disableNotification: Boolean = false, disableNotification: Boolean = false,
@@ -161,15 +413,25 @@ suspend inline fun TelegramBot.copyMessage(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChatId, toChat.id, messageId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
toChat.id,
fromChatId,
messageId,
entities,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/** /**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or * @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param * [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/ */
suspend inline fun TelegramBot.copyMessage( suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
fromChat: Chat, fromChat: Chat,
toChat: Chat,
messageId: MessageIdentifier, messageId: MessageIdentifier,
entities: TextSourcesList, entities: TextSourcesList,
disableNotification: Boolean = false, disableNotification: Boolean = false,
@@ -177,34 +439,14 @@ suspend inline fun TelegramBot.copyMessage(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChat.id, toChat.id, messageId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
toChat.id,
/** fromChat.id,
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or messageId,
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param entities,
*/ disableNotification,
suspend inline fun TelegramBot.copyMessage( protectContent,
toChatId: ChatIdentifier, replyToMessageId,
message: Message, allowSendingWithoutReply,
entities: TextSourcesList, replyMarkup
disableNotification: Boolean = false, )
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, toChatId, message.messageId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend inline fun TelegramBot.copyMessage(
toChat: Chat,
message: Message,
entities: TextSourcesList,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = copyMessage(message.chat, toChat, message.messageId, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)

View File

@@ -1,6 +1,8 @@
package dev.inmo.tgbotapi.extensions.api.send package dev.inmo.tgbotapi.extensions.api.send
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.*
import dev.inmo.tgbotapi.extensions.api.send.games.sendGame import dev.inmo.tgbotapi.extensions.api.send.games.sendGame
import dev.inmo.tgbotapi.extensions.api.send.media.* import dev.inmo.tgbotapi.extensions.api.send.media.*
import dev.inmo.tgbotapi.extensions.api.send.payments.sendInvoice import dev.inmo.tgbotapi.extensions.api.send.payments.sendInvoice
@@ -29,6 +31,10 @@ import dev.inmo.tgbotapi.types.payments.abstracts.Currency
import dev.inmo.tgbotapi.types.polls.* import dev.inmo.tgbotapi.types.polls.*
import dev.inmo.tgbotapi.types.venue.Venue import dev.inmo.tgbotapi.types.venue.Venue
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlin.js.JsName
import kotlin.jvm.JvmName
// Contact // Contact
@@ -950,7 +956,18 @@ suspend inline fun TelegramBot.reply(
protectContent: Boolean = false, protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = copyMessage(fromChatId, to.chat.id, messageId, text, parseMode, disableNotification, protectContent, to.messageId, allowSendingWithoutReply, replyMarkup) ) = copyMessage(
to.chat.id,
fromChatId,
messageId,
text,
parseMode,
disableNotification,
protectContent,
to.messageId,
allowSendingWithoutReply,
replyMarkup
)
suspend inline fun TelegramBot.reply( suspend inline fun TelegramBot.reply(
to: Message, to: Message,
@@ -995,6 +1012,80 @@ suspend fun TelegramBot.reply(
) )
} }
/**
* Will use [handleLiveLocation] with replying to [message] each time new message will be sent by live location update
*
* @see handleLiveLocation
*/
suspend fun TelegramBot.reply(
message: Message,
locationsFlow: Flow<EditLiveLocationInfo>,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false,
protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null
) = handleLiveLocation(
message.chat.id,
locationsFlow,
liveTimeMillis,
disableNotification,
protectContent,
message.messageId,
allowSendingWithoutReply
)
/**
* Will use [handleLiveLocation] with replying to [message] each time new message will be sent by live location update
*
* @see handleLiveLocation
*/
@JvmName("replyLiveLocationWithLocation")
@JsName("replyLiveLocationWithLocation")
suspend fun TelegramBot.reply(
message: Message,
locationsFlow: Flow<Location>,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false,
protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null
) {
handleLiveLocation(
message.chat.id,
locationsFlow,
liveTimeMillis,
disableNotification,
protectContent,
message.messageId,
allowSendingWithoutReply
)
}
/**
* Will use [handleLiveLocation] with replying to [message] each time new message will be sent by live location update
*
* @see handleLiveLocation
*/
@JvmName("replyLiveLocationWithLatLong")
@JsName("replyLiveLocationWithLatLong")
suspend fun TelegramBot.reply(
message: Message,
locationsFlow: Flow<Pair<Double, Double>>,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false,
protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null
) {
handleLiveLocation(
message.chat.id,
locationsFlow,
liveTimeMillis,
disableNotification,
protectContent,
message.messageId,
allowSendingWithoutReply
)
}
suspend fun TelegramBot.reply( suspend fun TelegramBot.reply(
to: Message, to: Message,
mediaFile: TelegramMediaFile, mediaFile: TelegramMediaFile,

View File

@@ -22,7 +22,7 @@ suspend fun <T> TelegramBot.withAction(
contract { contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
val botActionJob = CoroutineScope(coroutineContext).launch { val botActionJob = CoroutineScope(currentCoroutineContext()).launch {
while (isActive) { while (isActive) {
delay(refreshTime) delay(refreshTime)
safelyWithoutExceptions { safelyWithoutExceptions {

View File

@@ -0,0 +1,212 @@
package dev.inmo.tgbotapi.extensions.api.send
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.send.SendLiveLocation
import dev.inmo.tgbotapi.requests.send.SendStaticLocation
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.location.StaticLocation
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = execute(
SendLiveLocation(
chatId,
latitude,
longitude,
livePeriod,
horizontalAccuracy,
heading,
proximityAlertRadius,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLocation(
chatId: ChatIdentifier,
location: Location,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(
chatId,
location.latitude,
location.longitude,
livePeriod,
horizontalAccuracy,
heading,
proximityAlertRadius,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLocation(
chat: Chat,
latitude: Double,
longitude: Double,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(
chat.id,
latitude,
longitude,
livePeriod,
horizontalAccuracy,
heading,
proximityAlertRadius,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLocation(
chat: Chat,
location: Location,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(
chat.id,
location.latitude,
location.longitude,
livePeriod,
horizontalAccuracy,
heading,
proximityAlertRadius,
disableNotification,
protectContent,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLiveLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(chatId, latitude, longitude, livePeriod, horizontalAccuracy, heading, proximityAlertRadius, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLiveLocation(
chatId: ChatIdentifier,
location: Location,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(chatId, location.latitude, location.longitude, livePeriod, horizontalAccuracy, heading, proximityAlertRadius, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLiveLocation(
chat: Chat,
latitude: Double,
longitude: Double,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(chat.id, latitude, longitude, livePeriod, horizontalAccuracy, heading, proximityAlertRadius, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.sendLiveLocation(
chat: Chat,
location: Location,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
protectContent: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendLocation(chat.id, location.latitude, location.longitude, livePeriod, horizontalAccuracy, heading, proximityAlertRadius, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply, replyMarkup)

View File

@@ -6,6 +6,7 @@ import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.location.StaticLocation import dev.inmo.tgbotapi.types.location.StaticLocation
/** /**
@@ -40,7 +41,7 @@ suspend fun TelegramBot.sendLocation(
*/ */
suspend fun TelegramBot.sendLocation( suspend fun TelegramBot.sendLocation(
chatId: ChatIdentifier, chatId: ChatIdentifier,
location: StaticLocation, location: Location,
disableNotification: Boolean = false, disableNotification: Boolean = false,
protectContent: Boolean = false, protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
@@ -87,7 +88,7 @@ suspend fun TelegramBot.sendLocation(
*/ */
suspend fun TelegramBot.sendLocation( suspend fun TelegramBot.sendLocation(
chat: Chat, chat: Chat,
location: StaticLocation, location: Location,
disableNotification: Boolean = false, disableNotification: Boolean = false,
protectContent: Boolean = false, protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
@@ -125,7 +126,7 @@ suspend fun TelegramBot.sendStaticLocation(
*/ */
suspend fun TelegramBot.sendStaticLocation( suspend fun TelegramBot.sendStaticLocation(
chatId: ChatIdentifier, chatId: ChatIdentifier,
location: StaticLocation, location: Location,
disableNotification: Boolean = false, disableNotification: Boolean = false,
protectContent: Boolean = false, protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,
@@ -154,7 +155,7 @@ suspend fun TelegramBot.sendStaticLocation(
*/ */
suspend fun TelegramBot.sendStaticLocation( suspend fun TelegramBot.sendStaticLocation(
chat: Chat, chat: Chat,
location: StaticLocation, location: Location,
disableNotification: Boolean = false, disableNotification: Boolean = false,
protectContent: Boolean = false, protectContent: Boolean = false,
allowSendingWithoutReply: Boolean? = null, allowSendingWithoutReply: Boolean? = null,

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
package dev.inmo.tgbotapi.extensions.api.send.payments
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.send.payments.CreateInvoiceLink
import dev.inmo.tgbotapi.requests.send.payments.SendInvoice
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.payments.LabeledPrice
import dev.inmo.tgbotapi.types.payments.abstracts.Currency
suspend fun TelegramBot.createInvoiceLink(
title: String,
description: String,
payload: String,
providerToken: String,
currency: Currency,
prices: List<LabeledPrice>,
maxTipAmount: Int? = null,
suggestedTipAmounts: List<Int>? = null,
providerData: String? = null,
requireName: Boolean = false,
requirePhoneNumber: Boolean = false,
requireEmail: Boolean = false,
requireShippingAddress: Boolean = false,
shouldSendPhoneNumberToProvider: Boolean = false,
shouldSendEmailToProvider: Boolean = false,
priceDependOnShipAddress: Boolean = false
) = execute(
CreateInvoiceLink(title, description, payload, providerToken, currency, prices, maxTipAmount, suggestedTipAmounts ?.sorted(), providerData, requireName, requirePhoneNumber, requireEmail, requireShippingAddress, shouldSendPhoneNumberToProvider, shouldSendEmailToProvider, priceDependOnShipAddress)
)

View File

@@ -0,0 +1,54 @@
package dev.inmo.tgbotapi.extensions.api.stickers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.stickers.*
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.stickers.MaskPosition
suspend fun TelegramBot.createNewMaskAnimatedStickerSet(
userId: UserId,
name: String,
title: String,
sticker: FileId,
emojis: String,
maskPosition: MaskPosition
) = execute(
CreateNewMaskAnimatedStickerSet(userId, name, title, sticker, emojis, maskPosition)
)
suspend fun TelegramBot.createNewMaskAnimatedStickerSet(
userId: UserId,
name: String,
title: String,
sticker: MultipartFile,
emojis: String,
maskPosition: MaskPosition
) = execute(
CreateNewMaskAnimatedStickerSet(userId, name, title, sticker, emojis, maskPosition)
)
suspend fun TelegramBot.createNewMaskAnimatedStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: FileId,
emojis: String,
maskPosition: MaskPosition
) = createNewMaskAnimatedStickerSet(
user.id, name, title, sticker, emojis, maskPosition
)
suspend fun TelegramBot.createNewMaskAnimatedStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: MultipartFile,
emojis: String,
maskPosition: MaskPosition
) = createNewMaskAnimatedStickerSet(
user.id, name, title, sticker, emojis, maskPosition
)

View File

@@ -0,0 +1,54 @@
package dev.inmo.tgbotapi.extensions.api.stickers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.stickers.*
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.stickers.MaskPosition
suspend fun TelegramBot.createNewMaskStickerSet(
userId: UserId,
name: String,
title: String,
sticker: FileId,
emojis: String,
maskPosition: MaskPosition
) = execute(
CreateNewMaskStickerSet(userId, name, title, sticker, emojis, maskPosition)
)
suspend fun TelegramBot.createNewMaskStickerSet(
userId: UserId,
name: String,
title: String,
sticker: MultipartFile,
emojis: String,
maskPosition: MaskPosition
) = execute(
CreateNewMaskStickerSet(userId, name, title, sticker, emojis, maskPosition)
)
suspend fun TelegramBot.createNewMaskStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: FileId,
emojis: String,
maskPosition: MaskPosition
) = createNewMaskStickerSet(
user.id, name, title, sticker, emojis, maskPosition
)
suspend fun TelegramBot.createNewMaskStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: MultipartFile,
emojis: String,
maskPosition: MaskPosition
) = createNewMaskStickerSet(
user.id, name, title, sticker, emojis, maskPosition
)

View File

@@ -0,0 +1,54 @@
package dev.inmo.tgbotapi.extensions.api.stickers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.stickers.*
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.stickers.MaskPosition
suspend fun TelegramBot.createNewMaskVideoStickerSet(
userId: UserId,
name: String,
title: String,
sticker: FileId,
emojis: String,
maskPosition: MaskPosition
) = execute(
CreateNewMaskVideoStickerSet(userId, name, title, sticker, emojis, maskPosition)
)
suspend fun TelegramBot.createNewMaskVideoStickerSet(
userId: UserId,
name: String,
title: String,
sticker: MultipartFile,
emojis: String,
maskPosition: MaskPosition
) = execute(
CreateNewMaskVideoStickerSet(userId, name, title, sticker, emojis, maskPosition)
)
suspend fun TelegramBot.createNewMaskVideoStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: FileId,
emojis: String,
maskPosition: MaskPosition
) = createNewMaskVideoStickerSet(
user.id, name, title, sticker, emojis, maskPosition
)
suspend fun TelegramBot.createNewMaskVideoStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: MultipartFile,
emojis: String,
maskPosition: MaskPosition
) = createNewMaskVideoStickerSet(
user.id, name, title, sticker, emojis, maskPosition
)

View File

@@ -0,0 +1,50 @@
package dev.inmo.tgbotapi.extensions.api.stickers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.stickers.*
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.stickers.MaskPosition
suspend fun TelegramBot.createNewRegularAnimatedStickerSet(
userId: UserId,
name: String,
title: String,
sticker: FileId,
emojis: String
) = execute(
CreateNewRegularAnimatedStickerSet(userId, name, title, sticker, emojis)
)
suspend fun TelegramBot.createNewRegularAnimatedStickerSet(
userId: UserId,
name: String,
title: String,
sticker: MultipartFile,
emojis: String
) = execute(
CreateNewRegularAnimatedStickerSet(userId, name, title, sticker, emojis)
)
suspend fun TelegramBot.createNewRegularAnimatedStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: FileId,
emojis: String
) = createNewRegularAnimatedStickerSet(
user.id, name, title, sticker, emojis
)
suspend fun TelegramBot.createNewRegularAnimatedStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: MultipartFile,
emojis: String
) = createNewRegularAnimatedStickerSet(
user.id, name, title, sticker, emojis
)

View File

@@ -0,0 +1,50 @@
package dev.inmo.tgbotapi.extensions.api.stickers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.stickers.*
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.stickers.MaskPosition
suspend fun TelegramBot.createNewRegularStickerSet(
userId: UserId,
name: String,
title: String,
sticker: FileId,
emojis: String
) = execute(
CreateNewRegularStickerSet(userId, name, title, sticker, emojis)
)
suspend fun TelegramBot.createNewRegularStickerSet(
userId: UserId,
name: String,
title: String,
sticker: MultipartFile,
emojis: String
) = execute(
CreateNewRegularStickerSet(userId, name, title, sticker, emojis)
)
suspend fun TelegramBot.createNewRegularStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: FileId,
emojis: String
) = createNewRegularStickerSet(
user.id, name, title, sticker, emojis
)
suspend fun TelegramBot.createNewRegularStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: MultipartFile,
emojis: String
) = createNewRegularStickerSet(
user.id, name, title, sticker, emojis
)

View File

@@ -0,0 +1,50 @@
package dev.inmo.tgbotapi.extensions.api.stickers
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.stickers.*
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.stickers.MaskPosition
suspend fun TelegramBot.createNewRegularVideoStickerSet(
userId: UserId,
name: String,
title: String,
sticker: FileId,
emojis: String
) = execute(
CreateNewRegularVideoStickerSet(userId, name, title, sticker, emojis)
)
suspend fun TelegramBot.createNewRegularVideoStickerSet(
userId: UserId,
name: String,
title: String,
sticker: MultipartFile,
emojis: String
) = execute(
CreateNewRegularVideoStickerSet(userId, name, title, sticker, emojis)
)
suspend fun TelegramBot.createNewRegularVideoStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: FileId,
emojis: String
) = createNewRegularVideoStickerSet(
user.id, name, title, sticker, emojis
)
suspend fun TelegramBot.createNewRegularVideoStickerSet(
user: CommonUser,
name: String,
title: String,
sticker: MultipartFile,
emojis: String
) = createNewRegularVideoStickerSet(
user.id, name, title, sticker, emojis
)

View File

@@ -13,10 +13,11 @@ suspend fun TelegramBot.setWebhookInfo(
ipAddress: String? = null, ipAddress: String? = null,
maxAllowedConnections: Int? = null, maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null, allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null dropPendingUpdates: Boolean? = null,
secretToken: String? = null
) = execute( ) = execute(
SetWebhook( SetWebhook(
url, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates url, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates, secretToken
) )
) )
@@ -29,10 +30,11 @@ suspend fun TelegramBot.setWebhookInfo(
ipAddress: String? = null, ipAddress: String? = null,
maxAllowedConnections: Int? = null, maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null, allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null dropPendingUpdates: Boolean? = null,
secretToken: String? = null
) = execute( ) = execute(
SetWebhook( SetWebhook(
url, certificate, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates url, certificate, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates, secretToken
) )
) )
@@ -45,9 +47,10 @@ suspend fun TelegramBot.setWebhookInfo(
ipAddress: String? = null, ipAddress: String? = null,
maxAllowedConnections: Int? = null, maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null, allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null dropPendingUpdates: Boolean? = null,
secretToken: String? = null
) = execute( ) = execute(
SetWebhook( SetWebhook(
url, certificate, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates url, certificate, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates, secretToken
) )
) )

View File

@@ -0,0 +1,57 @@
package dev.inmo.tgbotapi.extensions.api.files
import com.benasher44.uuid.uuid4
import dev.inmo.micro_utils.common.filename
import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.MediaContent
import dev.inmo.tgbotapi.utils.fileExtension
import io.ktor.util.cio.use
import io.ktor.util.cio.writeChannel
import io.ktor.utils.io.copyTo
import kotlinx.coroutines.job
import java.io.File
import kotlin.coroutines.coroutineContext
suspend fun TelegramBot.downloadFileToTemp(
filePath: String
): File {
return downloadFile(
filePath,
File.createTempFile(uuid4().toString(), "_temp").apply {
deleteOnExit()
}
)
}
suspend fun TelegramBot.downloadFileToTemp(
pathedFile: PathedFile
) = downloadFileToTemp(
pathedFile.filePath
).apply {
runCatching {
renameTo(File(parentFile, "$nameWithoutExtension.${pathedFile.fileName.fileExtension}"))
}
}
suspend fun TelegramBot.downloadFileToTemp(
fileId: FileId
) = downloadFileToTemp(
getFileAdditionalInfo(fileId)
)
suspend fun TelegramBot.downloadFileToTemp(
file: TelegramMediaFile
): File = downloadFileToTemp(
getFileAdditionalInfo(file)
)
suspend fun TelegramBot.downloadFileToTemp(
file: MediaContent
) = downloadFileToTemp(
getFileAdditionalInfo(file.media)
)

View File

@@ -1,56 +1,20 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
} }
project.version = "$library_version" project.description = "Behaviour Builder DSL"
project.group = "$library_group"
project.description = "Behaviour Builder extension with built-in FSM"
apply from: "../publish.gradle" apply from: "$mppProjectWithSerializationPresetPath"
apply from: "$publishGradlePath"
repositories {
mavenLocal()
mavenCentral()
}
kotlin { kotlin {
jvm {
compilations.main {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js(IR) {
browser()
nodejs()
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib')
api project(":tgbotapi.behaviour_builder") api project(":tgbotapi.behaviour_builder")
api "dev.inmo:micro_utils.fsm.common:$micro_utils_version" api libs.microutils.fsm.common
} }
} }
} }
} }
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@@ -1,8 +1,9 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.*
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.fsm.common.* import dev.inmo.micro_utils.fsm.common.*
import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.TriggersHolder import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.TriggersHolder
@@ -46,16 +47,52 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
broadcastChannelsSize: Int, broadcastChannelsSize: Int,
onBufferOverflow: BufferOverflow, onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow<Update>?, upstreamUpdatesFlow: Flow<Update>?,
triggersHolder: TriggersHolder, triggersHolder: TriggersHolder
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
): BehaviourContextWithFSM<T> ): BehaviourContextWithFSM<T>
fun copy(
bot: TelegramBot = this.bot,
scope: CoroutineScope = this.scope,
broadcastChannelsSize: Int = 100,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND,
upstreamUpdatesFlow: Flow<Update>? = null,
triggersHolder: TriggersHolder = this.triggersHolder,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
): BehaviourContextWithFSM<T> = copy(
bot,
scope,
broadcastChannelsSize,
onBufferOverflow,
upstreamUpdatesFlow,
triggersHolder
)
fun copy(
bot: TelegramBot = this.bot,
scope: CoroutineScope = this.scope,
broadcastChannelsSize: Int = 100,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND,
upstreamUpdatesFlow: Flow<Update>? = null,
triggersHolder: TriggersHolder = this.triggersHolder,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>? = null
): BehaviourContextWithFSM<T> = copy(
bot,
scope,
broadcastChannelsSize,
onBufferOverflow,
upstreamUpdatesFlow,
triggersHolder,
onStateHandlingErrorHandler
)
companion object { companion object {
operator fun <T : State> invoke( operator fun <T : State> invoke(
behaviourContext: BehaviourContext, behaviourContext: BehaviourContext,
handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>, handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>,
statesManager: StatesManager<T> statesManager: StatesManager<T>,
) = DefaultBehaviourContextWithFSM<T>(behaviourContext, statesManager, handlers) onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
) = DefaultBehaviourContextWithFSM<T>(behaviourContext, statesManager, handlers, onStateHandlingErrorHandler)
} }
} }
@@ -84,16 +121,22 @@ inline fun <reified I : O, O: State> BehaviourContextWithFSM<O>.strictlyOn(handl
/** /**
* Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as * Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as
* [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states * [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states
* @param onStateHandlingErrorHandler Will be used in case if state handling has not been successfully completed in [launchStateHandling]
*/ */
class DefaultBehaviourContextWithFSM<T : State>( class DefaultBehaviourContextWithFSM<T : State>(
private val behaviourContext: BehaviourContext, private val behaviourContext: BehaviourContext,
private val statesManager: StatesManager<T>, private val statesManager: StatesManager<T>,
private val handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> private val handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>,
private val onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
) : BehaviourContext by behaviourContext, BehaviourContextWithFSM<T> { ) : BehaviourContext by behaviourContext, BehaviourContextWithFSM<T> {
private val updatesFlows = mutableMapOf<Any, DefaultBehaviourContextWithFSM<T>>() private val updatesFlows = mutableMapOf<Any, DefaultBehaviourContextWithFSM<T>>()
private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>() private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>()
private var actualHandlersList = additionalHandlers + handlers private var actualHandlersList = additionalHandlers + handlers
override suspend fun launchStateHandling(state: T, handlers: List<CheckableHandlerHolder<in T, T>>): T? {
return launchStateHandling(state, handlers, onStateHandlingErrorHandler)
}
private fun getSubContext(context: Any) = updatesFlows.getOrPut(context) { private fun getSubContext(context: Any) = updatesFlows.getOrPut(context) {
createSubContext() createSubContext()
} }
@@ -169,11 +212,26 @@ class DefaultBehaviourContextWithFSM<T : State>(
broadcastChannelsSize: Int, broadcastChannelsSize: Int,
onBufferOverflow: BufferOverflow, onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow<Update>?, upstreamUpdatesFlow: Flow<Update>?,
triggersHolder: TriggersHolder, triggersHolder: TriggersHolder
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM( ): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, triggersHolder, updatesFilter), behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, triggersHolder),
handlers, handlers,
statesManager statesManager,
onStateHandlingErrorHandler
)
override fun copy(
bot: TelegramBot,
scope: CoroutineScope,
broadcastChannelsSize: Int,
onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow<Update>?,
triggersHolder: TriggersHolder,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T>
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, triggersHolder),
handlers,
statesManager,
onStateHandlingErrorHandler
) )
} }

View File

@@ -4,18 +4,14 @@ import dev.inmo.micro_utils.coroutines.*
import dev.inmo.micro_utils.fsm.common.* import dev.inmo.micro_utils.fsm.common.*
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlin.reflect.KClass
@Deprecated("Will be removed soon")
typealias BehaviourContextWithFSMBuilder<T> = BehaviourContextWithFSM<T>
/** /**
* Creates [BehaviourContextWithFSM] via creating of [DefaultBehaviourContext] with [this] as [TelegramBot], * Creates [BehaviourContextWithFSM] via creating of [DefaultBehaviourContext] with [this] as [TelegramBot],
@@ -33,6 +29,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(), presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit> block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM( ): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
DefaultBehaviourContext( DefaultBehaviourContext(
@@ -41,7 +38,8 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
upstreamUpdatesFlow = upstreamUpdatesFlow upstreamUpdatesFlow = upstreamUpdatesFlow
), ),
presetHandlers, presetHandlers,
statesManager statesManager,
onStateHandlingErrorHandler
).apply { block() } ).apply { block() }
/** /**
@@ -55,6 +53,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(), presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit> block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM( ): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
upstreamUpdatesFlow, upstreamUpdatesFlow,
@@ -62,6 +61,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
defaultExceptionsHandler, defaultExceptionsHandler,
statesManager, statesManager,
presetHandlers, presetHandlers,
onStateHandlingErrorHandler,
block block
).run { ).run {
this to scope.launch { this to scope.launch {
@@ -94,6 +94,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(), presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit> block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM( ): DefaultBehaviourContextWithFSM<T> = BehaviourContextWithFSM(
DefaultBehaviourContext( DefaultBehaviourContext(
@@ -102,7 +103,8 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
upstreamUpdatesFlow = flowUpdatesFilter.allUpdatesFlow upstreamUpdatesFlow = flowUpdatesFilter.allUpdatesFlow
), ),
presetHandlers, presetHandlers,
statesManager statesManager,
onStateHandlingErrorHandler
).apply { block() } ).apply { block() }
/** /**
@@ -121,6 +123,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(), presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit> block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
) = FlowsUpdatesFilter().let { ) = FlowsUpdatesFilter().let {
buildBehaviourWithFSM( buildBehaviourWithFSM(
@@ -129,6 +132,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
defaultExceptionsHandler, defaultExceptionsHandler,
statesManager, statesManager,
presetHandlers, presetHandlers,
onStateHandlingErrorHandler,
block block
).run { ).run {
start() start()

View File

@@ -5,6 +5,8 @@ import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.fsm.common.StatesManager import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
import dev.inmo.tgbotapi.bot.ktor.telegramBot import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
@@ -39,6 +41,7 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(), presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
testServer: Boolean = false, testServer: Boolean = false,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit> block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
): TelegramBot = telegramBot( ): TelegramBot = telegramBot(
token, token,
@@ -52,6 +55,7 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
defaultExceptionsHandler, defaultExceptionsHandler,
statesManager, statesManager,
presetHandlers, presetHandlers,
onStateHandlingErrorHandler,
block block
) )
} }
@@ -76,6 +80,7 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(), presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
testServer: Boolean = false, testServer: Boolean = false,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit> block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
): Pair<TelegramBot, Job> { ): Pair<TelegramBot, Job> {
return telegramBot( return telegramBot(
@@ -89,6 +94,7 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
defaultExceptionsHandler, defaultExceptionsHandler,
statesManager, statesManager,
presetHandlers, presetHandlers,
onStateHandlingErrorHandler,
block block
) )
} }

View File

@@ -35,10 +35,10 @@ messages and filter messages for context which will be used in subcontext. Full
telegramBotWithBehaviour(TOKEN) { telegramBotWithBehaviour(TOKEN) {
onText( onText(
includeFilterByChatInBehaviourSubContext = true, // if false - last lambda will receive all messages instead of filtered by chat messages includeFilterByChatInBehaviourSubContext = true, // if false - last lambda will receive all messages instead of filtered by chat messages
additionalFilter = { message: CommonMessage<TextContent> -> additionalFilter = { message: TextMessage ->
// here you may check incoming message for any requirements before it will be passed to the main lambda // here you may check incoming message for any requirements before it will be passed to the main lambda
} }
) { message: CommonMessage<TextContent> -> // this here is `BehaviourContext` ) { message: TextMessage -> // this here is `BehaviourContext`
// here put your actions and additional waiters // here put your actions and additional waiters
} }
} }
@@ -50,7 +50,7 @@ Waiters targeted to get some content "here and now", they must be used inside so
```kotlin ```kotlin
telegramBotWithBehaviour(TOKEN) { telegramBotWithBehaviour(TOKEN) {
onCommand("start") { message: CommonMessage<TextContent> -> onCommand("start") { message: TextMessage ->
val userPhotos = waitPhoto( val userPhotos = waitPhoto(
SendTextMessage(it.chat.id, "Ok, send me some photo, please"), // init request, can be any `Request` object SendTextMessage(it.chat.id, "Ok, send me some photo, please"), // init request, can be any `Request` object
{ update: Update -> // That is update which is NOT passed requirements. In current context we expect some photo, but received something else { update: Update -> // That is update which is NOT passed requirements. In current context we expect some photo, but received something else

View File

@@ -1,55 +1,19 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
} }
project.version = "$library_version"
project.group = "$library_group"
project.description = "Behaviour Builder DSL" project.description = "Behaviour Builder DSL"
apply from: "../publish.gradle" apply from: "$mppProjectWithSerializationPresetPath"
apply from: "$publishGradlePath"
repositories {
mavenLocal()
mavenCentral()
}
kotlin { kotlin {
jvm {
compilations.main {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js(IR) {
browser()
nodejs()
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib')
api project(":tgbotapi.utils") api project(":tgbotapi.utils")
} }
} }
} }
} }
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@@ -6,7 +6,6 @@ import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.* import kotlinx.coroutines.*
/** /**

View File

@@ -55,8 +55,7 @@ interface BehaviourContext : FlowsUpdatesFilter, TelegramBot, CoroutineScope {
broadcastChannelsSize: Int = 100, broadcastChannelsSize: Int = 100,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND,
upstreamUpdatesFlow: Flow<Update>? = null, upstreamUpdatesFlow: Flow<Update>? = null,
triggersHolder: TriggersHolder = TriggersHolder(), triggersHolder: TriggersHolder = TriggersHolder()
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>? = null
): BehaviourContext ): BehaviourContext
} }
@@ -66,21 +65,16 @@ class DefaultBehaviourContext(
broadcastChannelsSize: Int = 100, broadcastChannelsSize: Int = 100,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND,
private val upstreamUpdatesFlow: Flow<Update>? = null, private val upstreamUpdatesFlow: Flow<Update>? = null,
override val triggersHolder: TriggersHolder = TriggersHolder(), override val triggersHolder: TriggersHolder = TriggersHolder()
private val updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>? = null
) : AbstractFlowsUpdatesFilter(), TelegramBot by bot, CoroutineScope by scope, BehaviourContext { ) : AbstractFlowsUpdatesFilter(), TelegramBot by bot, CoroutineScope by scope, BehaviourContext {
private val additionalUpdatesSharedFlow = MutableSharedFlow<Update>(0, broadcastChannelsSize, onBufferOverflow) private val additionalUpdatesSharedFlow = MutableSharedFlow<Update>(0, broadcastChannelsSize, onBufferOverflow)
override val allUpdatesFlow: Flow<Update> = (additionalUpdatesSharedFlow.asSharedFlow()).let { override val allUpdatesFlow: Flow<Update> = (additionalUpdatesSharedFlow.asSharedFlow()).let {
if (upstreamUpdatesFlow != null) { if (upstreamUpdatesFlow != null) {
(it + upstreamUpdatesFlow).distinctUntilChanged { old, new -> old.updateId == new.updateId } var lastHandledUpdate = -1L
} else { (it + upstreamUpdatesFlow).filter {
it (it.updateId > lastHandledUpdate).also { passed -> if (passed) { lastHandledUpdate = it.updateId } }
} }
}.let {
val updatesFilter = updatesFilter
if (updatesFilter != null) {
it.filter { updatesFilter(it) }
} else { } else {
it it
} }
@@ -93,9 +87,8 @@ class DefaultBehaviourContext(
broadcastChannelsSize: Int, broadcastChannelsSize: Int,
onBufferOverflow: BufferOverflow, onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow<Update>?, upstreamUpdatesFlow: Flow<Update>?,
triggersHolder: TriggersHolder, triggersHolder: TriggersHolder
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>? ): DefaultBehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, triggersHolder)
): DefaultBehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, triggersHolder, updatesFilter)
} }
fun BehaviourContext( fun BehaviourContext(
@@ -113,20 +106,17 @@ inline fun <T> BehaviourContext(
crossinline block: BehaviourContext.() -> T crossinline block: BehaviourContext.() -> T
) = DefaultBehaviourContext(bot, scope, upstreamUpdatesFlow = flowsUpdatesFilter.allUpdatesFlow, triggersHolder = triggersHolder).run(block) ) = DefaultBehaviourContext(bot, scope, upstreamUpdatesFlow = flowsUpdatesFilter.allUpdatesFlow, triggersHolder = triggersHolder).run(block)
/**
* Creates new [BehaviourContext] using its [BehaviourContext.copy] method
*
* @param updatesFilter This param will not be used anymore
*/
fun <BC : BehaviourContext> BC.createSubContext( fun <BC : BehaviourContext> BC.createSubContext(
scope: CoroutineScope = LinkedSupervisorScope(), scope: CoroutineScope = LinkedSupervisorScope(),
triggersHolder: TriggersHolder = this.triggersHolder, triggersHolder: TriggersHolder = this.triggersHolder,
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow, updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
updatesFilter: CustomBehaviourContextAndTypeReceiver<BC, Boolean, Update>? = null,
) = copy( ) = copy(
scope = scope, scope = scope,
updatesFilter = updatesFilter ?.let { _ ->
{
(this as? BC) ?.run {
updatesFilter(it)
} ?: true
}
},
upstreamUpdatesFlow = updatesUpstreamFlow, upstreamUpdatesFlow = updatesUpstreamFlow,
triggersHolder = triggersHolder triggersHolder = triggersHolder
) as BC ) as BC
@@ -155,63 +145,19 @@ suspend fun <T, BC : BehaviourContext> BC.createSubContextAndDoWithUpdatesFilter
scope: CoroutineScope = LinkedSupervisorScope(), scope: CoroutineScope = LinkedSupervisorScope(),
triggersHolder: TriggersHolder = this.triggersHolder, triggersHolder: TriggersHolder = this.triggersHolder,
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow, updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
updatesFilter: CustomBehaviourContextAndTypeReceiver<BC, Boolean, Update>? = null,
stopOnCompletion: Boolean = true, stopOnCompletion: Boolean = true,
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T> behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
): T { ): T {
return createSubContext( return createSubContext(
scope, scope,
triggersHolder, triggersHolder,
updatesUpstreamFlow, updatesUpstreamFlow
updatesFilter
).doInContext( ).doInContext(
stopOnCompletion, stopOnCompletion,
behaviourContextReceiver behaviourContextReceiver
) )
} }
/**
* Creates new one [BehaviourContext] using [createSubContext] and launches [behaviourContextReceiver] in a new context
* using [doInContext]
*
* @param stopOnCompletion ___TRUE BY DEFAULT___
*/
@Deprecated("Renamed", ReplaceWith("createSubContextAndDoWithUpdatesFilter", "dev.inmo.tgbotapi.extensions.behaviour_builder.createSubContextAndDoWithUpdatesFilter"))
suspend fun <T, BC : BehaviourContext> BC.doInSubContextWithUpdatesFilter(
updatesFilter: CustomBehaviourContextAndTypeReceiver<BC, Boolean, Update>?,
stopOnCompletion: Boolean = true,
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
scope: CoroutineScope = LinkedSupervisorScope(),
triggersHolder: TriggersHolder = this.triggersHolder,
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
): T {
return createSubContext(
scope,
triggersHolder,
updatesUpstreamFlow,
updatesFilter
).doInContext(
stopOnCompletion,
behaviourContextReceiver
)
}
@Deprecated("Redundant", ReplaceWith("createSubContextAndDoWithUpdatesFilter", "dev.inmo.tgbotapi.extensions.behaviour_builder.createSubContextAndDoWithUpdatesFilter"))
suspend fun <T> BehaviourContext.doInSubContext(
stopOnCompletion: Boolean = true,
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
scope: CoroutineScope = LinkedSupervisorScope(),
triggersHolder: TriggersHolder = this.triggersHolder,
behaviourContextReceiver: BehaviourContextReceiver<T>
) = createSubContextAndDoWithUpdatesFilter(
scope,
triggersHolder,
updatesUpstreamFlow,
updatesFilter = null,
stopOnCompletion,
behaviourContextReceiver
)
/** /**
* This method will cancel ALL subsequent contexts, expectations and waiters * This method will cancel ALL subsequent contexts, expectations and waiters
*/ */

View File

@@ -1,9 +1,9 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.coroutines.ExceptionHandler import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
import dev.inmo.tgbotapi.bot.ktor.telegramBot import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl

View File

@@ -4,7 +4,7 @@ import dev.inmo.micro_utils.coroutines.safelyWithResult
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.flatMap import dev.inmo.tgbotapi.extensions.utils.flatten
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
@@ -20,7 +20,6 @@ typealias NullableRequestBuilder<T> = suspend (Update) -> Request<T>?
/** /**
* @param initRequest If not null, this request will be sent by [bot] before returning value * @param initRequest If not null, this request will be sent by [bot] before returning value
* @param count If set, result [Flow] will return [count] elements on each [Flow.collect]
* @param errorFactory If set, this factory will be used to produce requests in case when user have sent incorrect data * @param errorFactory If set, this factory will be used to produce requests in case when user have sent incorrect data
* @param cancelRequestFactory If set, this factory will be used to produce requests in case when it is required to say * @param cancelRequestFactory If set, this factory will be used to produce requests in case when it is required to say
* user that chain of scenario has been cancelled * user that chain of scenario has been cancelled
@@ -33,7 +32,6 @@ typealias NullableRequestBuilder<T> = suspend (Update) -> Request<T>?
suspend fun <T> FlowsUpdatesFilter.expectFlow( suspend fun <T> FlowsUpdatesFilter.expectFlow(
bot: TelegramBot, bot: TelegramBot,
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
count: Int? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
cancelRequestFactory: NullableRequestBuilder<*> = { null }, cancelRequestFactory: NullableRequestBuilder<*> = { null },
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null }, cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
@@ -55,19 +53,13 @@ suspend fun <T> FlowsUpdatesFilter.expectFlow(
} else { } else {
result.getOrThrow() result.getOrThrow()
} }
}.flatMap() }.flatten()
val result = if (count == null) {
flow
} else {
flow.take(count)
}
initRequest ?.also { safelyWithoutExceptions { bot.execute(initRequest) } } initRequest ?.also { safelyWithoutExceptions { bot.execute(initRequest) } }
return result return flow
} }
/** /**
* @param initRequest If not null, this request will be sent by [bot] before returning value * @param initRequest If not null, this request will be sent by [bot] before returning value
* @param count If set, result [Flow] will return [count] elements on each [Flow.collect]
* @param errorFactory If set, this factory will be used to produce requests in case when user have sent incorrect data * @param errorFactory If set, this factory will be used to produce requests in case when user have sent incorrect data
* @param cancelRequestFactory If set, this factory will be used to produce requests in case when it is required to say * @param cancelRequestFactory If set, this factory will be used to produce requests in case when it is required to say
* user that chain of scenario has been cancelled * user that chain of scenario has been cancelled
@@ -76,14 +68,14 @@ suspend fun <T> FlowsUpdatesFilter.expectFlow(
* as is, but when it returns null, then will be called [cancelTrigger] (if it will return true - [cancelRequestFactory] * as is, but when it returns null, then will be called [cancelTrigger] (if it will return true - [cancelRequestFactory]
* will be called too), [errorFactory] and then will be returned null * will be called too), [errorFactory] and then will be returned null
*/ */
@RiskFeature(lowLevelRiskFeatureMessage)
suspend fun <T> BehaviourContext.expectFlow( suspend fun <T> BehaviourContext.expectFlow(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
count: Int? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
cancelRequestFactory: NullableRequestBuilder<*> = { null }, cancelRequestFactory: NullableRequestBuilder<*> = { null },
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null }, cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
filter: suspend (Update) -> List<T> filter: suspend (Update) -> List<T>
) = flowsUpdatesFilter.expectFlow(bot, initRequest, count, errorFactory, cancelRequestFactory, cancelTrigger, filter) ) = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory, cancelRequestFactory, cancelTrigger, filter)
/** /**
* @param initRequest If not null, this request will be sent by [bot] before returning value * @param initRequest If not null, this request will be sent by [bot] before returning value
@@ -103,7 +95,7 @@ suspend fun <T> FlowsUpdatesFilter.expectOne(
cancelRequestFactory: NullableRequestBuilder<*> = { null }, cancelRequestFactory: NullableRequestBuilder<*> = { null },
cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null }, cancelTrigger: suspend (Update) -> Boolean = { cancelRequestFactory(it) != null },
filter: suspend (Update) -> T? filter: suspend (Update) -> T?
): T = expectFlow(bot, initRequest, 1, errorFactory, cancelRequestFactory, cancelTrigger) { ): T = expectFlow(bot, initRequest, errorFactory, cancelRequestFactory, cancelTrigger) {
listOfNotNull(filter.invoke(it)) listOfNotNull(filter.invoke(it))
}.first() }.first()
@@ -117,6 +109,7 @@ suspend fun <T> FlowsUpdatesFilter.expectOne(
* as is, but when it returns null, then will be called [cancelTrigger] (if it will return true - [cancelRequestFactory] * as is, but when it returns null, then will be called [cancelTrigger] (if it will return true - [cancelRequestFactory]
* will be called too), [errorFactory] and then will be returned null * will be called too), [errorFactory] and then will be returned null
*/ */
@RiskFeature(lowLevelRiskFeatureMessage)
suspend fun <T> BehaviourContext.expectOne( suspend fun <T> BehaviourContext.expectOne(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },

View File

@@ -3,122 +3,60 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.callbackQueryUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.queries.callback.* import dev.inmo.tgbotapi.types.queries.callback.*
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias CallbackQueryMapper<T> = suspend T.() -> T? typealias CallbackQueryMapper<T> = suspend T.() -> T?
private suspend fun <O> BehaviourContext.waitCallbackQueries( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O> BehaviourContext.waitCallbackQueries(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<CallbackQuery>? = null, ): Flow<O> = expectFlow(
mapper: suspend CallbackQuery.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asCallbackQueryUpdate() ?.data (it.callbackQueryUpdateOrNull() ?.data as O).let(::listOfNotNull)
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun <reified T : CallbackQuery> BehaviourContext.waitCallbacks(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<T>? = null,
noinline mapper: CallbackQueryMapper<T>? = null
) : List<T> = waitCallbackQueries<T>(
count,
initRequest,
errorFactory,
filter ?.let {
{
(it as? T) ?.let { filter(it) } == true
}
}
) {
if (this is T) {
if (mapper == null) {
this
} else {
mapper(this)
}
} else {
null
}
} }
suspend fun BehaviourContext.waitDataCallbackQuery( suspend fun BehaviourContext.waitDataCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<DataCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<DataCallbackQuery>? = null,
mapper: CallbackQueryMapper<DataCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitGameShortNameCallbackQuery( suspend fun BehaviourContext.waitGameShortNameCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<GameShortNameCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<GameShortNameCallbackQuery>? = null,
mapper: CallbackQueryMapper<GameShortNameCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitInlineMessageIdCallbackQuery( suspend fun BehaviourContext.waitInlineMessageIdCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<InlineMessageIdCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<InlineMessageIdCallbackQuery>? = null,
mapper: CallbackQueryMapper<InlineMessageIdCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitInlineMessageIdDataCallbackQuery( suspend fun BehaviourContext.waitInlineMessageIdDataCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<InlineMessageIdDataCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<InlineMessageIdDataCallbackQuery>? = null,
mapper: CallbackQueryMapper<InlineMessageIdDataCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitInlineMessageIdGameShortNameCallbackQuery( suspend fun BehaviourContext.waitInlineMessageIdGameShortNameCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<InlineMessageIdGameShortNameCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<InlineMessageIdGameShortNameCallbackQuery>? = null,
mapper: CallbackQueryMapper<InlineMessageIdGameShortNameCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMessageCallbackQuery( suspend fun BehaviourContext.waitMessageCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<MessageCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<MessageCallbackQuery>? = null,
mapper: CallbackQueryMapper<MessageCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMessageDataCallbackQuery( suspend fun BehaviourContext.waitMessageDataCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<MessageDataCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<MessageDataCallbackQuery>? = null,
mapper: CallbackQueryMapper<MessageDataCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMessageGameShortNameCallbackQuery( suspend fun BehaviourContext.waitMessageGameShortNameCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<MessageGameShortNameCallbackQuery>(initRequest, errorFactory)
filter: SimpleFilter<MessageGameShortNameCallbackQuery>? = null,
mapper: CallbackQueryMapper<MessageGameShortNameCallbackQuery>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitUnknownCallbackQuery( suspend fun BehaviourContext.waitUnknownCallbackQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitCallbackQueries<UnknownCallbackQueryType>(initRequest, errorFactory)
filter: SimpleFilter<UnknownCallbackQueryType>? = null,
mapper: CallbackQueryMapper<UnknownCallbackQueryType>? = null
) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)

View File

@@ -1,49 +1,31 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.chatJoinRequestUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asChatJoinRequestUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias ChatJoinRequestsMapper = suspend ChatJoinRequest.() -> ChatJoinRequest? typealias ChatJoinRequestsMapper = suspend ChatJoinRequest.() -> ChatJoinRequest?
private suspend fun <O> BehaviourContext.waitChatJoinRequests( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O> BehaviourContext.internalWaitChatJoinRequests(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<ChatJoinRequest>? = null, ): Flow<O> = expectFlow(
mapper: suspend ChatJoinRequest.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asChatJoinRequestUpdate() ?.data (it.chatJoinRequestUpdateOrNull() ?.data as? O).let(::listOfNotNull)
if (data != null && (filter == null || filter(data))) { }
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
suspend fun BehaviourContext.waitChatJoinRequests( suspend fun BehaviourContext.waitChatJoinRequests(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) : Flow<ChatJoinRequest> = internalWaitChatJoinRequests(
filter: SimpleFilter<ChatJoinRequest>? = null,
mapper: ChatJoinRequestsMapper? = null
) : List<ChatJoinRequest> = waitChatJoinRequests(
count,
initRequest, initRequest,
errorFactory, errorFactory
filter )
) {
if (mapper == null) {
this
} else {
mapper(this)
}
}

View File

@@ -1,74 +1,39 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated
import dev.inmo.tgbotapi.types.update.CommonChatMemberUpdatedUpdate import dev.inmo.tgbotapi.types.update.CommonChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.types.update.MyChatMemberUpdatedUpdate import dev.inmo.tgbotapi.types.update.MyChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias ChatMemberUpdatedMapper<T> = suspend T.() -> T? typealias ChatMemberUpdatedMapper<T> = suspend T.() -> T?
private suspend inline fun <reified T : ChatMemberUpdatedUpdate> BehaviourContext.waitChatMemberUpdated( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O : ChatMemberUpdatedUpdate> BehaviourContext.waitChatMemberUpdatedWithFilter(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<T>? = null, ): Flow<ChatMemberUpdated> = expectFlow(
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>
): List<ChatMemberUpdated> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val casted = (it as? T) ?: return@expectFlow emptyList() (it as? O) ?.data.let(::listOfNotNull)
if (filter == null || filter(casted)) {
casted.data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun <reified T : ChatMemberUpdatedUpdate> BehaviourContext.waitChatMemberUpdatedWithFilter(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<T>? = null,
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) : List<ChatMemberUpdated> = waitChatMemberUpdated<T>(
count,
initRequest,
errorFactory,
filter,
) {
if (mapper == null) {
this
} else {
mapper(this)
}
} }
suspend fun BehaviourContext.waitChatMemberUpdated( suspend fun BehaviourContext.waitChatMemberUpdated(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, ) = waitChatMemberUpdatedWithFilter<ChatMemberUpdatedUpdate>(initRequest, errorFactory)
filter: SimpleFilter<ChatMemberUpdatedUpdate>? = null,
mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) = waitChatMemberUpdatedWithFilter<ChatMemberUpdatedUpdate>(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitCommonChatMemberUpdated( suspend fun BehaviourContext.waitCommonChatMemberUpdated(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, ) = waitChatMemberUpdatedWithFilter<CommonChatMemberUpdatedUpdate>(initRequest, errorFactory)
filter: SimpleFilter<CommonChatMemberUpdatedUpdate>? = null,
mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) = waitChatMemberUpdatedWithFilter<CommonChatMemberUpdatedUpdate>(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMyChatMemberUpdated( suspend fun BehaviourContext.waitMyChatMemberUpdated(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitChatMemberUpdatedWithFilter<MyChatMemberUpdatedUpdate>(initRequest, errorFactory)
filter: SimpleFilter<MyChatMemberUpdatedUpdate>? = null,
mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) = waitChatMemberUpdatedWithFilter<MyChatMemberUpdatedUpdate>(count, initRequest, errorFactory, filter, mapper)

View File

@@ -1,81 +1,37 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.chosenInlineResultUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asChosenInlineResultUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.* import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.*
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias ChosenInlineResultMapper<T> = suspend T.() -> T? typealias ChosenInlineResultMapper<T> = suspend T.() -> T?
private suspend fun <O> BehaviourContext.waitChosenInlineResultsUpdates( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O> BehaviourContext.waitChosenInlineResults(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<ChosenInlineResult>? = null, ): Flow<O> = expectFlow(
mapper: suspend ChosenInlineResult.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asChosenInlineResultUpdate() ?.data (it.chosenInlineResultUpdateOrNull() ?.data as? O).let(::listOfNotNull)
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun <reified T : ChosenInlineResult> BehaviourContext.waitChosenInlineResults(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<T>? = null,
noinline mapper: ChosenInlineResultMapper<T>? = null
) : List<T> = this@waitChosenInlineResults.waitChosenInlineResultsUpdates<T>(
count,
initRequest,
errorFactory,
filter ?.let {
{
(it as? T) ?.let { filter(it) } == true
}
}
) {
if (this is T) {
if (mapper == null) {
this
} else {
mapper(this)
}
} else {
null
}
} }
suspend fun BehaviourContext.waitChosenInlineResult( suspend fun BehaviourContext.waitChosenInlineResult(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitChosenInlineResults<ChosenInlineResult>(initRequest, errorFactory)
filter: SimpleFilter<ChosenInlineResult>? = null,
mapper: ChosenInlineResultMapper<ChosenInlineResult>? = null
) = waitChosenInlineResults(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLocationChosenInlineResult( suspend fun BehaviourContext.waitLocationChosenInlineResult(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitChosenInlineResults<LocationChosenInlineResult>(initRequest, errorFactory)
filter: SimpleFilter<LocationChosenInlineResult>? = null,
mapper: PollMapper<LocationChosenInlineResult>? = null
) = waitChosenInlineResults(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitBaseChosenInlineResult( suspend fun BehaviourContext.waitBaseChosenInlineResult(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitChosenInlineResults<BaseChosenInlineResult>(initRequest, errorFactory)
filter: SimpleFilter<BaseChosenInlineResult>? = null,
mapper: PollMapper<BaseChosenInlineResult>? = null
) = waitChosenInlineResults(count, initRequest, errorFactory, filter, mapper)

View File

@@ -2,276 +2,133 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.AudioMediaGroupContent import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupContent import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.InvoiceContent
import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.map
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T? typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
private suspend fun <O> BehaviourContext.waitCommonContent( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O : MessageContent> BehaviourContext.waitContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<CommonMessage<MessageContent>>? = null, ): Flow<O> = waitContentMessage<O>(initRequest, includeMediaGroups, errorFactory).map { it.content }
mapper: suspend CommonMessage<MessageContent>.() -> O?
): Flow<O> = expectFlow(
initRequest,
count,
errorFactory
) {
val messages = when (it) {
is SentMediaGroupUpdate -> {
if (includeMediaGroups) {
it.data.map { it as CommonMessage<MessageContent> }
} else {
emptyList()
}
}
is BaseSentMessageUpdate -> listOf(it.data)
else -> return@expectFlow emptyList()
}
messages.mapNotNull { message ->
val asCommonMessage = message as CommonMessage<MessageContent>
if (filter == null || filter(asCommonMessage)) {
asCommonMessage.mapper()
} else {
null
}
}
}
internal inline fun <reified T : MessageContent> contentConverter(
noinline mapper: CommonMessageToContentMapper<T>? = null
): suspend CommonMessage<MessageContent>.() -> T? = mapper ?.let {
{
if (content is T) {
@Suppress("UNCHECKED_CAST")
val message = (this as CommonMessage<T>)
safelyWithoutExceptions { mapper(message) }
} else {
null
}
}
} ?: { content as? T }
private suspend inline fun <reified T : MessageContent> BehaviourContext.waitContent(
count: Int = 1,
initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<CommonMessage<T>>? = null,
noinline mapper: CommonMessageToContentMapper<T>? = null
) : List<T> = waitCommonContent<T>(
count,
initRequest,
includeMediaGroups,
errorFactory,
filter ?.let {
{
it.withContent<T>() ?.let { filter(it) } == true
}
},
contentConverter(mapper)
).toList()
suspend fun BehaviourContext.waitContent( suspend fun BehaviourContext.waitContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContent<MessageContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MessageContent>>? = null,
mapper: CommonMessageToContentMapper<MessageContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitContact( suspend fun BehaviourContext.waitContact(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<ContactContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<ContactContent>>? = null,
mapper: CommonMessageToContentMapper<ContactContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDice( suspend fun BehaviourContext.waitDice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<DiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<DiceContent>>? = null,
mapper: CommonMessageToContentMapper<DiceContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitGame( suspend fun BehaviourContext.waitGame(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<GameContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<GameContent>>? = null,
mapper: CommonMessageToContentMapper<GameContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLocation( suspend fun BehaviourContext.waitLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<LocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<LocationContent>>? = null,
mapper: CommonMessageToContentMapper<LocationContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLiveLocation( suspend fun BehaviourContext.waitLiveLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<LiveLocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<LiveLocationContent>>? = null,
mapper: CommonMessageToContentMapper<LiveLocationContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitStaticLocation( suspend fun BehaviourContext.waitStaticLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<StaticLocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<StaticLocationContent>>? = null,
mapper: CommonMessageToContentMapper<StaticLocationContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPoll( suspend fun BehaviourContext.waitPoll(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<PollContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<PollContent>>? = null,
mapper: CommonMessageToContentMapper<PollContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitText( suspend fun BehaviourContext.waitText(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<TextContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<TextContent>>? = null,
mapper: CommonMessageToContentMapper<TextContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVenue( suspend fun BehaviourContext.waitVenue(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<VenueContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VenueContent>>? = null,
mapper: CommonMessageToContentMapper<VenueContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAudioMediaGroupContent( suspend fun BehaviourContext.waitAudioMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContent<AudioMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<AudioMediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<AudioMediaGroupContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDocumentMediaGroupContent( suspend fun BehaviourContext.waitDocumentMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContent<DocumentMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<DocumentMediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<DocumentMediaGroupContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMedia( suspend fun BehaviourContext.waitMedia(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContent<MediaContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MediaContent>>? = null,
mapper: CommonMessageToContentMapper<MediaContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAnyMediaGroupContent( suspend fun BehaviourContext.waitAnyMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContent<MediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<MediaGroupContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVisualMediaGroupContent( suspend fun BehaviourContext.waitVisualMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContent<VisualMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitTextedMediaContent( suspend fun BehaviourContext.waitTextedMediaContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContent<TextedMediaContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
mapper: CommonMessageToContentMapper<TextedMediaContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAnimation( suspend fun BehaviourContext.waitAnimation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<AnimationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<AnimationContent>>? = null,
mapper: CommonMessageToContentMapper<AnimationContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAudio( suspend fun BehaviourContext.waitAudio(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContent<AudioContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<AudioContent>>? = null,
mapper: CommonMessageToContentMapper<AudioContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDocument( suspend fun BehaviourContext.waitDocument(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContent<DocumentContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<DocumentContent>>? = null,
mapper: CommonMessageToContentMapper<DocumentContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPhoto( suspend fun BehaviourContext.waitPhoto(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContent<PhotoContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<PhotoContent>>? = null,
mapper: CommonMessageToContentMapper<PhotoContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitSticker( suspend fun BehaviourContext.waitSticker(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<StickerContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<StickerContent>>? = null,
mapper: CommonMessageToContentMapper<StickerContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideo( suspend fun BehaviourContext.waitVideo(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContent<VideoContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<VideoContent>>? = null,
mapper: CommonMessageToContentMapper<VideoContent>? = null
) = waitContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoNote( suspend fun BehaviourContext.waitVideoNote(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<VideoNoteContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VideoNoteContent>>? = null,
mapper: CommonMessageToContentMapper<VideoNoteContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVoice( suspend fun BehaviourContext.waitVoice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<VoiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VoiceContent>>? = null,
mapper: CommonMessageToContentMapper<VoiceContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitInvoice( suspend fun BehaviourContext.waitInvoice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContent<InvoiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<InvoiceContent>>? = null,
mapper: CommonMessageToContentMapper<InvoiceContent>? = null
) = waitContent(count, initRequest, false, errorFactory, filter, mapper)

View File

@@ -4,33 +4,25 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.utils.withContent import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.AudioMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.InvoiceContent
import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.toList
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>? typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
internal suspend fun <O : MessageContent> BehaviourContext.waitCommonMessage( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O : MessageContent> BehaviourContext.waitContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<CommonMessage<MessageContent>>? = null,
mapper: suspend CommonMessage<MessageContent>.() -> CommonMessage<O>?
): Flow<CommonMessage<O>> = expectFlow( ): Flow<CommonMessage<O>> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val messages = when (it) { val messages = when (it) {
@@ -45,13 +37,7 @@ internal suspend fun <O : MessageContent> BehaviourContext.waitCommonMessage(
else -> return@expectFlow emptyList() else -> return@expectFlow emptyList()
} }
messages.mapNotNull { message -> messages.mapNotNull { message ->
@Suppress("UNCHECKED_CAST") (message as? CommonMessage<*>) ?.withContent<O>()
val asCommonMessage = message as? CommonMessage<MessageContent> ?: return@mapNotNull null
if (filter == null || filter(asCommonMessage)) {
asCommonMessage.mapper()
} else {
null
}
} }
} }
@@ -72,209 +58,114 @@ internal inline fun <reified T : MessageContent> contentMessageConverter(
if (content is T) this as CommonMessage<T> else null if (content is T) this as CommonMessage<T> else null
} }
private suspend inline fun <reified T : MessageContent> BehaviourContext.waitContentMessage(
count: Int = 1,
initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<CommonMessage<T>>? = null,
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
) : List<CommonMessage<T>> = waitCommonMessage<T>(
count,
initRequest,
includeMediaGroups,
errorFactory,
filter ?.let {
{
it.withContent<T>() ?.let { filter(it) } == true
}
},
contentMessageConverter(mapper)
).toList()
suspend fun BehaviourContext.waitContentMessage( suspend fun BehaviourContext.waitContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContentMessage<MessageContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MessageContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<MessageContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitContactMessage( suspend fun BehaviourContext.waitContactMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<ContactContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<ContactContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<ContactContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDiceMessage( suspend fun BehaviourContext.waitDiceMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<DiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<DiceContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<DiceContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitGameMessage( suspend fun BehaviourContext.waitGameMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<GameContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<GameContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<GameContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLocationMessage( suspend fun BehaviourContext.waitLocationMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<LocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<LocationContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<LocationContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLiveLocationMessage( suspend fun BehaviourContext.waitLiveLocationMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<LiveLocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<LiveLocationContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<LiveLocationContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitStaticLocationMessage( suspend fun BehaviourContext.waitStaticLocationMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<StaticLocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<StaticLocationContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<StaticLocationContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPollMessage( suspend fun BehaviourContext.waitPollMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<PollContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<PollContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<PollContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitTextMessage( suspend fun BehaviourContext.waitTextMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<TextContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<TextContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<TextContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVenueMessage( suspend fun BehaviourContext.waitVenueMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<VenueContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VenueContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<VenueContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage( suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContentMessage<AudioMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<AudioMediaGroupContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<AudioMediaGroupContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage( suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContentMessage<DocumentMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<DocumentMediaGroupContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<DocumentMediaGroupContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMediaMessage( suspend fun BehaviourContext.waitMediaMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContentMessage<MediaContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MediaContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<MediaContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage( suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContentMessage<MediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MediaGroupContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<MediaGroupContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage( suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContentMessage<VisualMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<VisualMediaGroupContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitTextedMediaContentMessage( suspend fun BehaviourContext.waitTextedMediaContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitContentMessage<TextedMediaContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<TextedMediaContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAnimationMessage( suspend fun BehaviourContext.waitAnimationMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<AnimationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<AnimationContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<AnimationContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitAudioMessage( suspend fun BehaviourContext.waitAudioMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContentMessage<AudioContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<AudioContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<AudioContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDocumentMessage( suspend fun BehaviourContext.waitDocumentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContentMessage<DocumentContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<DocumentContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<DocumentContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPhotoMessage( suspend fun BehaviourContext.waitPhotoMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContentMessage<PhotoContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<PhotoContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<PhotoContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitStickerMessage( suspend fun BehaviourContext.waitStickerMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<StickerContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<StickerContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<StickerContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoMessage( suspend fun BehaviourContext.waitVideoMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitContentMessage<VideoContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<VideoContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<VideoContent>? = null
) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoNoteMessage( suspend fun BehaviourContext.waitVideoNoteMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<VideoNoteContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VideoNoteContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<VideoNoteContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVoiceMessage( suspend fun BehaviourContext.waitVoiceMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<VoiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VoiceContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<VoiceContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitInvoiceMessage( suspend fun BehaviourContext.waitInvoiceMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitContentMessage<InvoiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<InvoiceContent>>? = null,
mapper: CommonMessageToCommonMessageMapper<InvoiceContent>? = null
) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper)

View File

@@ -3,250 +3,130 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter
import dev.inmo.tgbotapi.extensions.utils.asCommonMessage
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.AudioMediaGroupContent import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupContent import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent import kotlinx.coroutines.flow.Flow
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupContent import kotlinx.coroutines.flow.map
import dev.inmo.tgbotapi.types.message.content.InvoiceContent
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
import kotlinx.coroutines.flow.toList
private suspend fun <O> BehaviourContext.waitEditedCommonMessage( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O : MessageContent> BehaviourContext.waitEditedContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true, includeMediaGroups: Boolean = true,
noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<O> = waitEditedContentMessage<O>(initRequest, includeMediaGroups, errorFactory).map { it.content }
suspend fun BehaviourContext.waitEditedMessageContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<CommonMessage<MessageContent>>? = null, includeMediaGroups: Boolean = true
mapper: suspend CommonMessage<MessageContent>.() -> O? ) = waitEditedContent<MessageContent>(initRequest, includeMediaGroups, errorFactory)
): List<O> = expectFlow(
initRequest,
count,
errorFactory
) {
val messages = when (it) {
is BaseEditMessageUpdate -> {
val commonMessage = it.data.asCommonMessage()
if (commonMessage !is MediaGroupMessage<*> || includeMediaGroups) {
listOf(commonMessage)
} else {
emptyList()
}
}
else -> return@expectFlow emptyList()
}
messages.mapNotNull { message ->
val asCommonMessage = message as CommonMessage<MessageContent>
if (filter == null || filter(asCommonMessage)) {
asCommonMessage.mapper()
} else {
null
}
}
}.toList().toList()
private suspend inline fun <reified T : MessageContent> BehaviourContext.waitEditedContent(
count: Int = 1,
initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<CommonMessage<T>>? = null,
noinline mapper: CommonMessageToContentMapper<T>? = null
) : List<T> = waitEditedCommonMessage<T>(
count,
initRequest,
includeMediaGroups,
errorFactory,
filter ?.let {
{
it.withContent<T>() ?.let { filter(it) } == true
}
},
contentConverter(mapper)
)
suspend fun BehaviourContext.waitEditedContentMessage( suspend fun BehaviourContext.waitEditedContentMessage(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitEditedContent<MessageContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MessageContent>>? = null,
mapper: CommonMessageToContentMapper<MessageContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedContact( suspend fun BehaviourContext.waitEditedContact(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<ContactContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<ContactContent>>? = null,
mapper: CommonMessageToContentMapper<ContactContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedDice( suspend fun BehaviourContext.waitEditedDice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<DiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<DiceContent>>? = null,
mapper: CommonMessageToContentMapper<DiceContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedGame( suspend fun BehaviourContext.waitEditedGame(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<GameContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<GameContent>>? = null,
mapper: CommonMessageToContentMapper<GameContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedLocation( suspend fun BehaviourContext.waitEditedLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<LocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<LocationContent>>? = null,
mapper: CommonMessageToContentMapper<LocationContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedLiveLocation( suspend fun BehaviourContext.waitEditedLiveLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<LiveLocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<LiveLocationContent>>? = null,
mapper: CommonMessageToContentMapper<LiveLocationContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedStaticLocation( suspend fun BehaviourContext.waitEditedStaticLocation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<StaticLocationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<StaticLocationContent>>? = null,
mapper: CommonMessageToContentMapper<StaticLocationContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedText( suspend fun BehaviourContext.waitEditedText(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<TextContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<TextContent>>? = null,
mapper: CommonMessageToContentMapper<TextContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedVenue( suspend fun BehaviourContext.waitEditedVenue(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<VenueContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VenueContent>>? = null,
mapper: CommonMessageToContentMapper<VenueContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedAudioMediaGroupContent( suspend fun BehaviourContext.waitEditedAudioMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitEditedContent<AudioMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<AudioMediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<AudioMediaGroupContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedDocumentMediaGroupContent( suspend fun BehaviourContext.waitEditedDocumentMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitEditedContent<DocumentMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<DocumentMediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<DocumentMediaGroupContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedMedia( suspend fun BehaviourContext.waitEditedMedia(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitEditedContent<MediaContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MediaContent>>? = null,
mapper: CommonMessageToContentMapper<MediaContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedAnyMediaGroupContent( suspend fun BehaviourContext.waitEditedAnyMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitEditedContent<MediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<MediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<MediaGroupContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedVisualMediaGroupContent( suspend fun BehaviourContext.waitEditedVisualMediaGroupContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitEditedContent<VisualMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<VisualMediaGroupContent>>? = null,
mapper: CommonMessageToContentMapper<VisualMediaGroupContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedTextedMediaContent( suspend fun BehaviourContext.waitEditedTextedMediaContent(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = true
includeMediaGroups: Boolean = true, ) = waitEditedContent<TextedMediaContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<TextedMediaContent>>? = null,
mapper: CommonMessageToContentMapper<TextedMediaContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedAnimation( suspend fun BehaviourContext.waitEditedAnimation(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<AnimationContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<AnimationContent>>? = null,
mapper: CommonMessageToContentMapper<AnimationContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedAudio( suspend fun BehaviourContext.waitEditedAudio(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitEditedContent<AudioContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<AudioContent>>? = null,
mapper: CommonMessageToContentMapper<AudioContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedDocument( suspend fun BehaviourContext.waitEditedDocument(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitEditedContent<DocumentContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<DocumentContent>>? = null,
mapper: CommonMessageToContentMapper<DocumentContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedPhoto( suspend fun BehaviourContext.waitEditedPhoto(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitEditedContent<PhotoContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<PhotoContent>>? = null,
mapper: CommonMessageToContentMapper<PhotoContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedSticker( suspend fun BehaviourContext.waitEditedSticker(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<StickerContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<StickerContent>>? = null,
mapper: CommonMessageToContentMapper<StickerContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedVideo( suspend fun BehaviourContext.waitEditedVideo(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, includeMediaGroups: Boolean = false
includeMediaGroups: Boolean = false, ) = waitEditedContent<VideoContent>(initRequest, includeMediaGroups, errorFactory)
filter: SimpleFilter<CommonMessage<VideoContent>>? = null,
mapper: CommonMessageToContentMapper<VideoContent>? = null
) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedVideoNote( suspend fun BehaviourContext.waitEditedVideoNote(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<VideoNoteContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VideoNoteContent>>? = null,
mapper: CommonMessageToContentMapper<VideoNoteContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedVoice( suspend fun BehaviourContext.waitEditedVoice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<VoiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<VoiceContent>>? = null,
mapper: CommonMessageToContentMapper<VoiceContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedInvoice( suspend fun BehaviourContext.waitEditedInvoice(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEditedContent<InvoiceContent>(initRequest, false, errorFactory)
filter: SimpleFilter<CommonMessage<InvoiceContent>>? = null,
mapper: CommonMessageToContentMapper<InvoiceContent>? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)

View File

@@ -0,0 +1,149 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.commonMessageOrNull
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
@RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : MessageContent> BehaviourContext.waitEditedContentMessage(
initRequest: Request<*>? = null,
includeMediaGroups: Boolean = true,
noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<CommonMessage<O>> = expectFlow(
initRequest,
errorFactory
) {
val messages = when (it) {
is BaseEditMessageUpdate -> {
val commonMessage = it.data.commonMessageOrNull() ?: return@expectFlow emptyList()
if (commonMessage !is MediaGroupMessage<*> || includeMediaGroups) {
listOf(commonMessage)
} else {
emptyList()
}
}
else -> return@expectFlow emptyList()
}
messages.mapNotNull { message ->
(message as CommonMessage<*>).withContent<O>()
}
}
suspend fun BehaviourContext.waitEditedMessageContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = true
) = waitEditedContentMessage<MessageContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedContactMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<ContactContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedDiceMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<DiceContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedGameMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<GameContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedLocationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<LocationContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedLiveLocationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<LiveLocationContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedStaticLocationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<StaticLocationContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedTextMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<TextContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedVenueMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<VenueContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedAudioMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = true
) = waitEditedContentMessage<AudioMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedDocumentMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = true
) = waitEditedContentMessage<DocumentMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedMediaMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = false
) = waitEditedContentMessage<MediaContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedAnyMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = true
) = waitEditedContentMessage<MediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedVisualMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = true
) = waitEditedContentMessage<VisualMediaGroupContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedTextedMediaContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = true
) = waitEditedContentMessage<TextedMediaContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedAnimationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<AnimationContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedAudioMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = false
) = waitEditedContentMessage<AudioContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedDocumentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = false
) = waitEditedContentMessage<DocumentContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedPhotoMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = false
) = waitEditedContentMessage<PhotoContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedStickerMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<StickerContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedVideoMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
includeMediaGroups: Boolean = false
) = waitEditedContentMessage<VideoContent>(initRequest, includeMediaGroups, errorFactory)
suspend fun BehaviourContext.waitEditedVideoNoteMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<VideoNoteContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedVoiceMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<VoiceContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedInvoiceMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<InvoiceContent>(initRequest, false, errorFactory)

View File

@@ -3,282 +3,136 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.asBaseSentMessageUpdate
import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
import dev.inmo.tgbotapi.types.message.PrivateEventMessage
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias EventMessageToEventMapper<T> = suspend ChatEventMessage<T>.() -> T? typealias EventMessageToEventMapper<T> = suspend ChatEventMessage<T>.() -> T?
private suspend fun <O> BehaviourContext.waitEventMessages( @RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : ChatEvent> BehaviourContext.waitEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ): Flow<O> = expectFlow(
filter: SimpleFilter<ChatEventMessage<ChatEvent>>? = null,
mapper: suspend ChatEventMessage<ChatEvent>.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asBaseSentMessageUpdate() ?.data ?.asChatEventMessage() it.baseSentMessageUpdateOrNull() ?.data ?.chatEventMessageOrNull() ?.withEvent<O>() ?.chatEvent.let(::listOfNotNull)
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun <reified T : ChatEvent> BehaviourContext.waitEvents(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<ChatEventMessage<T>>? = null,
noinline mapper: EventMessageToEventMapper<T>? = null
) : List<T> = waitEventMessages<T>(
initRequest,
errorFactory,
count,
filter ?.let {
{
(it.chatEvent as? T) ?.let { filter(it as ChatEventMessage<T>) } == true
}
}
) {
if (chatEvent is T) {
@Suppress("UNCHECKED_CAST")
val message = (this as ChatEventMessage<T>)
if (mapper == null) {
message.chatEvent
} else {
mapper(message)
}
} else {
null
}
} }
suspend fun BehaviourContext.waitChannelEvents( suspend fun BehaviourContext.waitChannelEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<ChannelEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<ChannelEvent>>? = null,
mapper: EventMessageToEventMapper<ChannelEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPrivateEvents( suspend fun BehaviourContext.waitPrivateEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<PrivateEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<PrivateEvent>>? = null,
mapper: EventMessageToEventMapper<PrivateEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitChatEvents( suspend fun BehaviourContext.waitChatEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<ChatEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<ChatEvent>>? = null,
mapper: EventMessageToEventMapper<ChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
mapper: EventMessageToEventMapper<VideoChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatStartedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
mapper: EventMessageToEventMapper<VideoChatStarted>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatEndedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
mapper: EventMessageToEventMapper<VideoChatEnded>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
@Deprecated("Renamed as Video instead of Voice")
suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
mapper: EventMessageToEventMapper<VideoChatParticipantsInvited>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatEvents( suspend fun BehaviourContext.waitVideoChatEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<VideoChatEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
mapper: EventMessageToEventMapper<VideoChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatStartedEvents( suspend fun BehaviourContext.waitVideoChatStartedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<VideoChatStarted>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
mapper: EventMessageToEventMapper<VideoChatStarted>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatEndedEvents( suspend fun BehaviourContext.waitVideoChatEndedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<VideoChatEnded>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
mapper: EventMessageToEventMapper<VideoChatEnded>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitVideoChatParticipantsInvitedEvents( suspend fun BehaviourContext.waitVideoChatParticipantsInvitedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<VideoChatParticipantsInvited>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
mapper: EventMessageToEventMapper<VideoChatParticipantsInvited>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents( suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<MessageAutoDeleteTimerChanged>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<MessageAutoDeleteTimerChanged>>? = null,
mapper: EventMessageToEventMapper<MessageAutoDeleteTimerChanged>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPublicChatEvents( suspend fun BehaviourContext.waitPublicChatEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<PublicChatEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<PublicChatEvent>>? = null,
mapper: EventMessageToEventMapper<PublicChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitCommonEvents( suspend fun BehaviourContext.waitCommonEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<CommonEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<CommonEvent>>? = null,
mapper: EventMessageToEventMapper<CommonEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitGroupEvents( suspend fun BehaviourContext.waitGroupEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<GroupEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<GroupEvent>>? = null,
mapper: EventMessageToEventMapper<GroupEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitSupergroupEvents( suspend fun BehaviourContext.waitSupergroupEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<SupergroupEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<SupergroupEvent>>? = null,
mapper: EventMessageToEventMapper<SupergroupEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitChannelChatCreatedEvents( suspend fun BehaviourContext.waitChannelChatCreatedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<ChannelChatCreated>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<ChannelChatCreated>>? = null,
mapper: EventMessageToEventMapper<ChannelChatCreated>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitDeleteChatPhotoEvents( suspend fun BehaviourContext.waitDeleteChatPhotoEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<DeleteChatPhoto>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<DeleteChatPhoto>>? = null,
mapper: EventMessageToEventMapper<DeleteChatPhoto>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitGroupChatCreatedEvents( suspend fun BehaviourContext.waitGroupChatCreatedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<GroupChatCreated>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<GroupChatCreated>>? = null,
mapper: EventMessageToEventMapper<GroupChatCreated>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLeftChatMemberEvents( suspend fun BehaviourContext.waitLeftChatMemberEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<LeftChatMember>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<LeftChatMember>>? = null,
mapper: EventMessageToEventMapper<LeftChatMember>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitNewChatPhotoEvents( suspend fun BehaviourContext.waitNewChatPhotoEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<NewChatPhoto>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<NewChatPhoto>>? = null,
mapper: EventMessageToEventMapper<NewChatPhoto>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitNewChatMembersEvents( suspend fun BehaviourContext.waitNewChatMembersEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<NewChatMembers>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<NewChatMembers>>? = null,
mapper: EventMessageToEventMapper<NewChatMembers>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitNewChatTitleEvents( suspend fun BehaviourContext.waitNewChatTitleEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<NewChatTitle>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<NewChatTitle>>? = null,
mapper: EventMessageToEventMapper<NewChatTitle>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitPinnedMessageEvents( suspend fun BehaviourContext.waitPinnedMessageEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<PinnedMessage>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<PinnedMessage>>? = null,
mapper: EventMessageToEventMapper<PinnedMessage>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitProximityAlertTriggeredEvents( suspend fun BehaviourContext.waitProximityAlertTriggeredEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<ProximityAlertTriggered>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<ProximityAlertTriggered>>? = null,
mapper: EventMessageToEventMapper<ProximityAlertTriggered>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitSupergroupChatCreatedEvents( suspend fun BehaviourContext.waitSupergroupChatCreatedEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<SupergroupChatCreated>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<SupergroupChatCreated>>? = null,
mapper: EventMessageToEventMapper<SupergroupChatCreated>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitSuccessfulPaymentEvents( suspend fun BehaviourContext.waitSuccessfulPaymentEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<SuccessfulPaymentEvent>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<SuccessfulPaymentEvent>>? = null,
mapper: EventMessageToEventMapper<SuccessfulPaymentEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitUserLoggedInEvents( suspend fun BehaviourContext.waitUserLoggedInEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<UserLoggedIn>(initRequest, errorFactory)
filter: SimpleFilter<ChatEventMessage<UserLoggedIn>>? = null,
mapper: EventMessageToEventMapper<UserLoggedIn>? = null
) = waitEvents(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitWebAppDataEvents( suspend fun BehaviourContext.waitWebAppDataEvents(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitEvents<WebAppData>(initRequest, errorFactory)
filter: SimpleFilter<PrivateEventMessage<WebAppData>>? = null,
mapper: EventMessageToEventMapper<WebAppData>? = null
) = waitEvents(count, initRequest, errorFactory, filter ?.let { { it is PrivateEventMessage && filter(it) } }, mapper)

View File

@@ -0,0 +1,135 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
@RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : ChatEvent> BehaviourContext.waitEventsMessages(
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<ChatEventMessage<O>> = expectFlow(
initRequest,
errorFactory
) {
it.baseSentMessageUpdateOrNull() ?.data ?.chatEventMessageOrNull() ?.withEvent<O>().let(::listOfNotNull)
}
suspend fun BehaviourContext.waitChannelEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ChannelEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitPrivateEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<PrivateEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitChatEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ChatEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitVideoChatEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<VideoChatEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitVideoChatStartedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<VideoChatStarted>(initRequest, errorFactory)
suspend fun BehaviourContext.waitVideoChatEndedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<VideoChatEnded>(initRequest, errorFactory)
suspend fun BehaviourContext.waitVideoChatParticipantsInvitedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<VideoChatParticipantsInvited>(initRequest, errorFactory)
suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<MessageAutoDeleteTimerChanged>(initRequest, errorFactory)
suspend fun BehaviourContext.waitPublicChatEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<PublicChatEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitCommonEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<CommonEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitGroupEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<GroupEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitSupergroupEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<SupergroupEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitChannelChatCreatedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ChannelChatCreated>(initRequest, errorFactory)
suspend fun BehaviourContext.waitDeleteChatPhotoEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<DeleteChatPhoto>(initRequest, errorFactory)
suspend fun BehaviourContext.waitGroupChatCreatedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<GroupChatCreated>(initRequest, errorFactory)
suspend fun BehaviourContext.waitLeftChatMemberEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<LeftChatMember>(initRequest, errorFactory)
suspend fun BehaviourContext.waitNewChatPhotoEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<NewChatPhoto>(initRequest, errorFactory)
suspend fun BehaviourContext.waitNewChatMembersEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<NewChatMembers>(initRequest, errorFactory)
suspend fun BehaviourContext.waitNewChatTitleEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<NewChatTitle>(initRequest, errorFactory)
suspend fun BehaviourContext.waitPinnedMessageEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<PinnedMessage>(initRequest, errorFactory)
suspend fun BehaviourContext.waitProximityAlertTriggeredEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<ProximityAlertTriggered>(initRequest, errorFactory)
suspend fun BehaviourContext.waitSupergroupChatCreatedEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<SupergroupChatCreated>(initRequest, errorFactory)
suspend fun BehaviourContext.waitSuccessfulPaymentEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<SuccessfulPaymentEvent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitUserLoggedInEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<UserLoggedIn>(initRequest, errorFactory)
suspend fun BehaviourContext.waitWebAppDataEventsMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEventsMessages<WebAppData>(initRequest, errorFactory)

View File

@@ -1,80 +1,36 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.inlineQueryUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asInlineQueryUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.InlineQueries.query.* import dev.inmo.tgbotapi.types.InlineQueries.query.*
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias InlineQueryMapper<T> = suspend T.() -> T? typealias InlineQueryMapper<T> = suspend T.() -> T?
private suspend fun <O> BehaviourContext.waitInlineQueries( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O : InlineQuery> BehaviourContext.waitInlineQueries(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<InlineQuery>? = null, ): Flow<O> = expectFlow(
mapper: suspend InlineQuery.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asInlineQueryUpdate() ?.data (it.inlineQueryUpdateOrNull() ?.data as? O).let(::listOfNotNull)
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun <reified T : InlineQuery> BehaviourContext.waitInlines(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<T>? = null,
noinline mapper: InlineQueryMapper<T>? = null
) : List<T> = waitInlineQueries<T>(
count,
initRequest,
errorFactory,
filter ?.let {
{
(it as? T) ?.let { casted -> filter(casted) } == true
}
}
) {
if (this is T) {
if (mapper == null) {
this
} else {
mapper(this)
}
} else {
null
}
} }
suspend fun BehaviourContext.waitAnyInlineQuery( suspend fun BehaviourContext.waitAnyInlineQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitInlineQueries<InlineQuery>(initRequest, errorFactory)
filter: SimpleFilter<InlineQuery>? = null,
mapper: InlineQueryMapper<InlineQuery>? = null
) = waitInlines(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitBaseInlineQuery( suspend fun BehaviourContext.waitBaseInlineQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitInlineQueries<BaseInlineQuery>(initRequest, errorFactory)
filter: SimpleFilter<BaseInlineQuery>? = null,
mapper: InlineQueryMapper<BaseInlineQuery>? = null
) = waitInlines(count, initRequest, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitLocationInlineQuery( suspend fun BehaviourContext.waitLocationInlineQuery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitInlineQueries<LocationInlineQuery>(initRequest, errorFactory)
filter: SimpleFilter<LocationInlineQuery>? = null,
mapper: InlineQueryMapper<LocationInlineQuery>? = null
) = waitInlines(count, initRequest, errorFactory, filter, mapper)

View File

@@ -1,70 +1,45 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.utils.asSentMediaGroupUpdate import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.AudioMediaGroupContent import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupContent import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent import kotlinx.coroutines.flow.Flow
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupContent import kotlinx.coroutines.flow.map
import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.toList
typealias MediaGroupFilter<T> = suspend List<MediaGroupMessage<T>>.() -> Boolean typealias MediaGroupFilter<T> = SimpleFilter<List<MediaGroupMessage<T>>>
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.buildMediaGroupWaiter(
count: Int = 1, @RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : MediaGroupContent> BehaviourContext.buildMediaGroupWaiter(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
noinline filter: MediaGroupFilter<T>? = null ): Flow<List<O>> = buildMediaGroupMessagesWaiter<O>(initRequest, errorFactory).map { it.map { it.content } }
) = flowsUpdatesFilter.expectFlow(bot, initRequest, count, errorFactory) { update ->
update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup as List<MediaGroupMessage<T>>))) {
listOf(
mediaGroup.map { it.content as T }
)
} else {
null
}
} ?: emptyList()
}.take(count).toList()
suspend fun BehaviourContext.waitMediaGroup( suspend fun BehaviourContext.waitMediaGroup(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = buildMediaGroupWaiter<MediaGroupContent>(initRequest, errorFactory)
filter: MediaGroupFilter<MediaGroupContent>? = null
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitPlaylist( suspend fun BehaviourContext.waitPlaylist(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = buildMediaGroupWaiter<AudioMediaGroupContent>(initRequest, errorFactory)
filter: MediaGroupFilter<AudioMediaGroupContent>? = null
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitDocumentsGroup( suspend fun BehaviourContext.waitDocumentsGroup(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = buildMediaGroupWaiter<DocumentMediaGroupContent>(initRequest, errorFactory)
filter: MediaGroupFilter<DocumentMediaGroupContent>? = null
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVisualGallery( suspend fun BehaviourContext.waitVisualGallery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = buildMediaGroupWaiter<VisualMediaGroupContent>(initRequest, errorFactory)
filter: MediaGroupFilter<VisualMediaGroupContent>? = null
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitPhotoGallery( suspend fun BehaviourContext.waitPhotoGallery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = buildMediaGroupWaiter<PhotoContent>(initRequest, errorFactory)
filter: MediaGroupFilter<PhotoContent>? = null
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVideoGallery( suspend fun BehaviourContext.waitVideoGallery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = buildMediaGroupWaiter<VideoContent>(initRequest, errorFactory)
filter: MediaGroupFilter<VideoContent>? = null
) = buildMediaGroupWaiter(count, initRequest, errorFactory, filter)

View File

@@ -0,0 +1,49 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.sentMediaGroupUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
@RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified T : MediaGroupContent> BehaviourContext.buildMediaGroupMessagesWaiter(
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<List<MediaGroupMessage<T>>> = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory) { update ->
update.sentMediaGroupUpdateOrNull() ?.data ?.let { mediaGroup ->
val mapped = mediaGroup.mapNotNull { it.withContent<T>() }
listOf(
mapped
)
} ?: emptyList()
}
suspend fun BehaviourContext.waitMediaGroupMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = buildMediaGroupMessagesWaiter<MediaGroupContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitPlaylistMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = buildMediaGroupMessagesWaiter<AudioMediaGroupContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitDocumentsGroupMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = buildMediaGroupMessagesWaiter<DocumentMediaGroupContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitVisualGalleryMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = buildMediaGroupMessagesWaiter<VisualMediaGroupContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitPhotoGalleryMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = buildMediaGroupMessagesWaiter<PhotoContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitVideoGalleryMessages(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = buildMediaGroupMessagesWaiter<VideoContent>(initRequest, errorFactory)

View File

@@ -1,65 +1,30 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.messageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate import dev.inmo.tgbotapi.extensions.utils.passportMessageOrNull
import dev.inmo.tgbotapi.extensions.utils.asPassportMessage
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.PassportMessage import dev.inmo.tgbotapi.types.message.PassportMessage
import dev.inmo.tgbotapi.types.passport.PassportData import dev.inmo.tgbotapi.types.passport.PassportData
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias PassportMessageMapper = suspend PassportMessage.() -> PassportData typealias PassportMessageMapper = suspend PassportMessage.() -> PassportData
@RiskFeature("Do not use this message directly, use waitPassportMessagesWith or waitAnyPassportMessages instead") @RiskFeature(lowLevelRiskFeatureMessage)
suspend fun <O> BehaviourContext.waitPassportMessages( suspend inline fun <reified O : EncryptedPassportElement> BehaviourContext.waitPassportMessagesWith(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ): Flow<O> = expectFlow(
filter: SimpleFilter<PassportMessage>? = null,
mapper: suspend PassportMessage.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asMessageUpdate() ?.data ?.asPassportMessage() ?: return@expectFlow emptyList() it.messageUpdateOrNull() ?.data ?.passportMessageOrNull() ?.passportData ?.data ?.filterIsInstance<O>() ?: emptyList()
if (filter == null || filter(data)) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
suspend inline fun <reified T : EncryptedPassportElement> BehaviourContext.waitPassportMessagesWith(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<PassportMessage>? = null,
noinline mapper: PassportMessageMapper? = null
) : List<PassportData> = waitPassportMessages(
initRequest,
errorFactory,
count,
filter
) {
if (passportData.data.any { it is T }) {
if (mapper == null) {
passportData
} else {
mapper(this)
}
} else {
null
}
} }
suspend fun BehaviourContext.waitAnyPassportMessages( suspend fun BehaviourContext.waitAnyPassportMessages(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitPassportMessagesWith<EncryptedPassportElement>(initRequest, errorFactory)
filter: SimpleFilter<PassportMessage>? = null,
mapper: PassportMessageMapper? = null
) = waitPassportMessagesWith<EncryptedPassportElement>(count, initRequest, errorFactory, filter, mapper)

View File

@@ -1,64 +1,19 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.pollAnswerUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asPollAnswerUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.polls.PollAnswer import dev.inmo.tgbotapi.types.polls.PollAnswer
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.Flow
typealias PollAnswerMapper = suspend PollAnswer.() -> PollAnswer? typealias PollAnswerMapper = suspend PollAnswer.() -> PollAnswer?
private suspend fun <O> BehaviourContext.waitPollsAnswers(
count: Int = 1,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<PollAnswer>? = null,
mapper: suspend PollAnswer.() -> O?
): List<O> = expectFlow(
initRequest,
count,
errorFactory
) {
val data = it.asPollAnswerUpdate() ?.data
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun BehaviourContext.waitPollAnswers(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<PollAnswer>? = null,
noinline mapper: PollAnswerMapper? = null
) : List<PollAnswer> = this@waitPollAnswers.waitPollsAnswers<PollAnswer>(
count,
initRequest,
errorFactory,
filter ?.let {
{
(it as? PollAnswer) ?.let { filter(it) } == true
}
}
) {
if (mapper == null) {
this
} else {
mapper(this)
}
}
/**
* This wait will be triggered only for stopped polls and polls, which are sent by the bot
*/
suspend fun BehaviourContext.waitPollAnswers( suspend fun BehaviourContext.waitPollAnswers(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ): Flow<PollAnswer> = expectFlow(
filter: SimpleFilter<PollAnswer>? = null, initRequest,
mapper: PollAnswerMapper? = null errorFactory
) = waitPollAnswers(count, initRequest, errorFactory, filter, mapper) ) {
it.pollAnswerUpdateOrNull() ?.data.let(::listOfNotNull)
}

View File

@@ -1,59 +1,24 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.pollUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asPollUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.polls.* import dev.inmo.tgbotapi.types.polls.*
import kotlinx.coroutines.flow.toList import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
typealias PollMapper<T> = suspend T.() -> T? typealias PollMapper<T> = suspend T.() -> T?
private suspend fun <O> BehaviourContext.waitPollsUpdates( @RiskFeature(lowLevelRiskFeatureMessage)
count: Int = 1, suspend inline fun <reified O : Poll> BehaviourContext.waitPolls(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null }
filter: SimpleFilter<Poll>? = null, ): Flow<O> = expectFlow(
mapper: suspend Poll.() -> O?
): List<O> = expectFlow(
initRequest, initRequest,
count,
errorFactory errorFactory
) { ) {
val data = it.asPollUpdate() ?.data (it.pollUpdateOrNull() ?.data as? O).let(::listOfNotNull)
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
private suspend inline fun <reified T : Poll> BehaviourContext.waitPolls(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<T>? = null,
noinline mapper: PollMapper<T>? = null
) : List<T> = this@waitPolls.waitPollsUpdates<T>(
count,
initRequest,
errorFactory,
filter ?.let {
{
(it as? T) ?.let { filter(it) } == true
}
}
) {
if (this is T) {
if (mapper == null) {
this
} else {
mapper(this)
}
} else {
null
}
} }
/** /**
@@ -61,30 +26,21 @@ private suspend inline fun <reified T : Poll> BehaviourContext.waitPolls(
*/ */
suspend fun BehaviourContext.waitPollUpdates( suspend fun BehaviourContext.waitPollUpdates(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitPolls<Poll>(initRequest, errorFactory)
filter: SimpleFilter<Poll>? = null,
mapper: PollMapper<Poll>? = null
) = waitPolls(count, initRequest, errorFactory, filter, mapper)
/** /**
* This wait will be triggered only for stopped polls and polls, which are sent by the bot * This wait will be triggered only for stopped polls and polls, which are sent by the bot
*/ */
suspend fun BehaviourContext.waitQuizPollUpdates( suspend fun BehaviourContext.waitQuizPollUpdates(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitPolls<QuizPoll>(initRequest, errorFactory)
filter: SimpleFilter<QuizPoll>? = null,
mapper: PollMapper<QuizPoll>? = null
) = waitPolls(count, initRequest, errorFactory, filter, mapper)
/** /**
* This wait will be triggered only for stopped polls and polls, which are sent by the bot * This wait will be triggered only for stopped polls and polls, which are sent by the bot
*/ */
suspend fun BehaviourContext.waitRegularPollUpdates( suspend fun BehaviourContext.waitRegularPollUpdates(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ) = waitPolls<RegularPoll>(initRequest, errorFactory)
filter: SimpleFilter<RegularPoll>? = null,
mapper: PollMapper<RegularPoll>? = null
) = waitPolls(count, initRequest, errorFactory, filter, mapper)

View File

@@ -1,49 +1,19 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.preCheckoutQueryUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asPreCheckoutQueryUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.Flow
typealias PreCheckoutQueryMapper = suspend PreCheckoutQuery.() -> PreCheckoutQuery? typealias PreCheckoutQueryMapper = suspend PreCheckoutQuery.() -> PreCheckoutQuery?
private suspend fun <O> BehaviourContext.waitPreCheckoutQueries(
count: Int = 1,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<PreCheckoutQuery>? = null,
mapper: suspend PreCheckoutQuery.() -> O?
): List<O> = expectFlow(
initRequest,
count,
errorFactory
) {
val data = it.asPreCheckoutQueryUpdate() ?.data
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
suspend fun BehaviourContext.waitPreCheckoutQueries( suspend fun BehaviourContext.waitPreCheckoutQueries(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ): Flow<PreCheckoutQuery> = expectFlow(
filter: SimpleFilter<PreCheckoutQuery>? = null,
mapper: PreCheckoutQueryMapper? = null
) : List<PreCheckoutQuery> = waitPreCheckoutQueries(
count,
initRequest, initRequest,
errorFactory, errorFactory
filter
) { ) {
if (mapper == null) { it.preCheckoutQueryUpdateOrNull() ?.data.let(::listOfNotNull)
this
} else {
mapper(this)
}
} }

View File

@@ -1,49 +1,19 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations 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.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.shippingQueryUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asShippingQueryUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.payments.ShippingQuery import dev.inmo.tgbotapi.types.payments.ShippingQuery
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.Flow
typealias ShippingQueryMapper = suspend ShippingQuery.() -> ShippingQuery? typealias ShippingQueryMapper = suspend ShippingQuery.() -> ShippingQuery?
private suspend fun <O> BehaviourContext.waitShippingQueries(
count: Int = 1,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
filter: SimpleFilter<ShippingQuery>? = null,
mapper: suspend ShippingQuery.() -> O?
): List<O> = expectFlow(
initRequest,
count,
errorFactory
) {
val data = it.asShippingQueryUpdate() ?.data
if (data != null && (filter == null || filter(data))) {
data.mapper().let(::listOfNotNull)
} else {
emptyList()
}
}.toList().toList()
suspend fun BehaviourContext.waitShippingQueries( suspend fun BehaviourContext.waitShippingQueries(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null }
count: Int = 1, ): Flow<ShippingQuery> = expectFlow(
filter: SimpleFilter<ShippingQuery>? = null,
mapper: ShippingQueryMapper? = null
) : List<ShippingQuery> = waitShippingQueries(
count,
initRequest, initRequest,
errorFactory, errorFactory
filter
) { ) {
if (mapper == null) { (it.shippingQueryUpdateOrNull() ?.data).let(::listOfNotNull)
this
} else {
mapper(this)
}
} }

View File

@@ -2,13 +2,13 @@ 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.types.queries.callback.CallbackQuery 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
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
import dev.inmo.tgbotapi.types.payments.ShippingQuery import dev.inmo.tgbotapi.types.payments.ShippingQuery
import dev.inmo.tgbotapi.types.queries.callback.CallbackQuery
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
/** /**

View File

@@ -9,8 +9,8 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CallbackQueryFilte
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.ByUserCallbackQueryMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserCallbackQueryMarkerFactory
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.plus import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate import dev.inmo.tgbotapi.extensions.utils.callbackQueryUpdateOrNull
import dev.inmo.tgbotapi.types.queries.callback.* import dev.inmo.tgbotapi.types.queries.callback.*
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@@ -21,7 +21,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : CallbackQuery> B
markerFactory: MarkerFactory<in T, Any> = ByUserCallbackQueryMarkerFactory, markerFactory: MarkerFactory<in T, Any> = ByUserCallbackQueryMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asCallbackQueryUpdate() ?.data as? T) ?.let(::listOfNotNull) (it.callbackQueryUpdateOrNull() ?.data as? T) ?.let(::listOfNotNull)
} }
/** /**
@@ -111,7 +111,7 @@ suspend fun <BC : BehaviourContext> BC.onDataCallbackQuery(
markerFactory: MarkerFactory<in DataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory, markerFactory: MarkerFactory<in DataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DataCallbackQuery> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DataCallbackQuery>
) = onDataCallbackQuery( ) = onDataCallbackQuery(
initialFilter = initialFilter + { initialFilter = initialFilter * {
it.data.matches(dataRegex) it.data.matches(dataRegex)
}, },
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -239,7 +239,7 @@ suspend fun <BC : BehaviourContext> BC.onInlineMessageIdDataCallbackQuery(
markerFactory: MarkerFactory<in InlineMessageIdDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory, markerFactory: MarkerFactory<in InlineMessageIdDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InlineMessageIdDataCallbackQuery> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InlineMessageIdDataCallbackQuery>
) = onInlineMessageIdDataCallbackQuery( ) = onInlineMessageIdDataCallbackQuery(
initialFilter = initialFilter + { initialFilter = initialFilter * {
it.data.matches(dataRegex) it.data.matches(dataRegex)
}, },
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -367,7 +367,7 @@ suspend fun <BC : BehaviourContext> BC.onMessageDataCallbackQuery(
markerFactory: MarkerFactory<in MessageDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory, markerFactory: MarkerFactory<in MessageDataCallbackQuery, Any> = ByUserCallbackQueryMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MessageDataCallbackQuery> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MessageDataCallbackQuery>
) = onMessageDataCallbackQuery( ) = onMessageDataCallbackQuery(
initialFilter = initialFilter + { initialFilter = initialFilter * {
it.data.matches(dataRegex) it.data.matches(dataRegex)
}, },
subcontextUpdatesFilter, subcontextUpdatesFilter,

View File

@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.ChatJoinRequestFil
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
import dev.inmo.tgbotapi.extensions.utils.asChatJoinRequestUpdate import dev.inmo.tgbotapi.extensions.utils.chatJoinRequestUpdateOrNull
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -29,5 +29,5 @@ suspend fun <BC : BehaviourContext> BC.onChatJoinRequest(
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) {
(it.asChatJoinRequestUpdate() ?.data) ?.let(::listOfNotNull) (it.chatJoinRequestUpdateOrNull() ?.data) ?.let(::listOfNotNull)
} }

View File

@@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.*
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.ByUserIdChosenInlineResultMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserIdChosenInlineResultMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asChosenInlineResultUpdate import dev.inmo.tgbotapi.extensions.utils.chosenInlineResultUpdateOrNull
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.* import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.*
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -16,7 +16,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : ChosenInlineResu
markerFactory: MarkerFactory<in T, Any> = ByUserIdChosenInlineResultMarkerFactory, markerFactory: MarkerFactory<in T, Any> = ByUserIdChosenInlineResultMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asChosenInlineResultUpdate() ?.data as? T) ?.let(::listOfNotNull) (it.chosenInlineResultUpdateOrNull() ?.data as? T) ?.let(::listOfNotNull)
} }
/** /**

View File

@@ -10,10 +10,10 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByCha
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.asBotCommandTextSource import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextMessage
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@@ -21,9 +21,9 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onText( ): Job = onText(
CommonMessageFilter<TextContent> { message -> CommonMessageFilter<TextContent> { message ->
val content = message.content val content = message.content
@@ -34,7 +34,7 @@ internal suspend fun <BC : BehaviourContext> BC.commandUncounted(
true true
} }
sizeRequirement && textSources.any { sizeRequirement && textSources.any {
commandRegex.matches(it.asBotCommandTextSource() ?.command ?: return@any false) commandRegex.matches(it.botCommandTextSourceOrNull() ?.command ?: return@any false)
} }
}.let { }.let {
initialFilter ?.times(it) ?: it initialFilter ?.times(it) ?: it
@@ -48,9 +48,9 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = runCatchingSafely { ): Job = runCatchingSafely {
commandUncounted( commandUncounted(
commandRegex, commandRegex,
@@ -77,35 +77,35 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = command(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = command(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onCommand( 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = command(commandRegex, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = command(commandRegex, requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onCommand( 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = command( ) = command(
commandRegex, commandRegex,
requireOnlyCommandInMessage = false, requireOnlyCommandInMessage = false,
@@ -123,9 +123,9 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
) = commandWithArgs( ) = commandWithArgs(
command.toRegex(), command.toRegex(),
initialFilter = initialFilter, initialFilter = initialFilter,
@@ -137,15 +137,15 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = commandWithArgs(commandRegex, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = commandWithArgs(commandRegex, initialFilter, subcontextUpdatesFilter, markerFactory, 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Array<String>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
): Job = onCommandWithArgs(command.toRegex(), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = onCommandWithArgs(command.toRegex(), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -8,22 +8,21 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByCha
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.asBotCommandTextSource import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextMessage
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.PreviewFeature import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@PreviewFeature @PreviewFeature
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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = onText( ): Job = onText(
CommonMessageFilter<TextContent> { message -> CommonMessageFilter<TextContent> { message ->
val content = message.content val content = message.content
@@ -34,7 +33,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommand(
true true
} }
sizeRequirement && textSources.any { sizeRequirement && textSources.any {
val command = it.asBotCommandTextSource() ?.command ?: return@any false val command = it.botCommandTextSourceOrNull() ?.command ?: return@any false
!triggersHolder.handleableCommandsHolder.isHandled(command) !triggersHolder.handleableCommandsHolder.isHandled(command)
} }
}.let { }.let {
@@ -49,17 +48,17 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
): Job = unhandledCommand(requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ): Job = unhandledCommand(requireOnlyCommandInMessage, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
@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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, Map<String, Array<String>>> scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Map<String, Array<String>>>
) = onUnhandledCommand( ) = onUnhandledCommand(
requireOnlyCommandInMessage = false, requireOnlyCommandInMessage = false,
initialFilter = initialFilter, initialFilter = initialFilter,
@@ -75,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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, CommonMessage<TextContent>, 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

@@ -12,12 +12,9 @@ import dev.inmo.tgbotapi.extensions.utils.whenCommonMessage
import dev.inmo.tgbotapi.types.files.TelegramMediaFile import dev.inmo.tgbotapi.types.files.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.AudioMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.InvoiceContent
import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate
typealias CommonMessageFilter<T> = SimpleFilter<CommonMessage<T>> typealias CommonMessageFilter<T> = SimpleFilter<CommonMessage<T>>
@@ -75,9 +72,9 @@ 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, CommonMessage<ContactContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<ContactContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<ContactContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -99,9 +96,9 @@ 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, CommonMessage<DiceContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<DiceContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DiceContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -123,9 +120,9 @@ 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, CommonMessage<GameContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<GameContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<GameContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -147,9 +144,9 @@ 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, CommonMessage<LocationContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<LocationContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LocationContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -171,9 +168,9 @@ 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, CommonMessage<LiveLocationContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LiveLocationMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<LiveLocationContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in LiveLocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LiveLocationContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LiveLocationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -195,9 +192,9 @@ 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, CommonMessage<StaticLocationContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StaticLocationMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<StaticLocationContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in StaticLocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StaticLocationContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StaticLocationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -219,9 +216,9 @@ 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, CommonMessage<PollContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<PollContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PollMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PollContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -243,9 +240,9 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -267,9 +264,9 @@ suspend fun <BC : BehaviourContext> BC.onText(
*/ */
suspend fun <BC : BehaviourContext> BC.onVenue( suspend fun <BC : BehaviourContext> BC.onVenue(
initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups, initialFilter: CommonMessageFilter<VenueContent>? = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VenueContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VenueContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VenueContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -291,9 +288,9 @@ suspend fun <BC : BehaviourContext> BC.onVenue(
*/ */
suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup( suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
initialFilter: CommonMessageFilter<AudioMediaGroupContent>? = null, initialFilter: CommonMessageFilter<AudioMediaGroupContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioMediaGroupContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<AudioMediaGroupContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioMediaGroupContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -315,9 +312,9 @@ suspend fun <BC : BehaviourContext> BC.onAudioMediaGroup(
*/ */
suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent( suspend fun <BC : BehaviourContext> BC.onDocumentMediaGroupContent(
initialFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null, initialFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentMediaGroupContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<DocumentMediaGroupContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentMediaGroupContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -339,9 +336,9 @@ 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, CommonMessage<TextedMediaContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextedMediaContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedMediaContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -363,9 +360,9 @@ 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, CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -387,9 +384,9 @@ 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, CommonMessage<MediaContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<MediaContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -411,9 +408,9 @@ 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, CommonMessage<AnimationContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -435,9 +432,9 @@ 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, CommonMessage<AudioContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -459,9 +456,9 @@ 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, CommonMessage<DocumentContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -483,9 +480,9 @@ 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, CommonMessage<PhotoContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -507,9 +504,9 @@ 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, CommonMessage<StickerContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<StickerContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StickerContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -531,9 +528,9 @@ 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, CommonMessage<VideoContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -555,9 +552,9 @@ 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, CommonMessage<VideoNoteContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VideoNoteContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoNoteContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -579,9 +576,9 @@ 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, CommonMessage<VoiceContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -603,9 +600,9 @@ 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, CommonMessage<InvoiceContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<InvoiceContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<InvoiceContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage>
) = onContentMessageWithType( ) = onContentMessageWithType(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,

View File

@@ -20,21 +20,13 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilte
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.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.utils.asEditMessageUpdate import dev.inmo.tgbotapi.extensions.utils.editMessageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.withContent import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.types.files.TelegramMediaFile import dev.inmo.tgbotapi.types.files.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.abstracts.*
import dev.inmo.tgbotapi.types.message.content.AudioMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.InvoiceContent
import dev.inmo.tgbotapi.types.message.content.MediaCollectionContent
import dev.inmo.tgbotapi.types.message.content.MediaContent
import dev.inmo.tgbotapi.types.message.content.MessageContent
import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.PreviewFeature
internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onEditedContent( internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent> BC.onEditedContent(
initialFilter: CommonMessageFilter<T>? = null, initialFilter: CommonMessageFilter<T>? = null,
@@ -43,7 +35,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MessageContent>
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
when (it) { when (it) {
is BaseEditMessageUpdate -> (it.asEditMessageUpdate() ?.data ?.withContent<T>()) is BaseEditMessageUpdate -> (it.editMessageUpdateOrNull() ?.data ?.withContent<T>())
else -> null else -> null
} ?.let(::listOfNotNull) } ?.let(::listOfNotNull)
} }
@@ -87,9 +79,9 @@ 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, CommonMessage<ContactContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ContactMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<ContactContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in ContactMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<ContactContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ContactMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -111,9 +103,9 @@ 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, CommonMessage<DiceContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DiceMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<DiceContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DiceContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DiceMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -135,9 +127,9 @@ 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, CommonMessage<GameContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, GameMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<GameContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in GameMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<GameContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, GameMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -159,9 +151,9 @@ 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, CommonMessage<LocationContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, LocationMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<LocationContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in LocationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<LocationContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, LocationMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -183,9 +175,9 @@ 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, CommonMessage<TextContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -207,9 +199,9 @@ 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, CommonMessage<VenueContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VenueMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VenueContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VenueMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VenueContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VenueMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -231,9 +223,9 @@ suspend fun <BC : BehaviourContext> BC.onEditedVenue(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup( suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup(
initialFilter: CommonMessageFilter<AudioMediaGroupContent>? = null, initialFilter: CommonMessageFilter<AudioMediaGroupContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioMediaGroupContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMediaGroupMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<AudioMediaGroupContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioMediaGroupContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMediaGroupMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -255,9 +247,9 @@ suspend fun <BC : BehaviourContext> BC.onEditedAudioMediaGroup(
*/ */
suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent( suspend fun <BC : BehaviourContext> BC.onEditedDocumentMediaGroupContent(
initialFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null, initialFilter: CommonMessageFilter<DocumentMediaGroupContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentMediaGroupContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMediaGroupMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<DocumentMediaGroupContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMediaGroupMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentMediaGroupContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMediaGroupMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -279,9 +271,9 @@ 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, CommonMessage<TextedMediaContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMediaMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<TextedMediaContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in TextedMediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedMediaContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMediaMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -303,9 +295,9 @@ 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, CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaCollectionMessage<TelegramMediaFile>, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<MediaCollectionContent<TelegramMediaFile>>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaCollectionMessage<TelegramMediaFile>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaCollectionContent<TelegramMediaFile>>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaCollectionMessage<TelegramMediaFile>>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -327,9 +319,9 @@ 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, CommonMessage<MediaContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<MediaContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -351,9 +343,9 @@ 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, CommonMessage<AnimationContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AnimationMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AnimationMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AnimationMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -375,9 +367,9 @@ 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, CommonMessage<AudioContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, AudioMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in AudioMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, AudioMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -399,9 +391,9 @@ 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, CommonMessage<DocumentContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, DocumentMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in DocumentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, DocumentMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -423,9 +415,9 @@ 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, CommonMessage<PhotoContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PhotoMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PhotoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PhotoMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -447,9 +439,9 @@ 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, CommonMessage<StickerContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, StickerMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<StickerContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in StickerMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<StickerContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, StickerMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -471,9 +463,9 @@ 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, CommonMessage<VideoContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -495,9 +487,9 @@ 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, CommonMessage<VideoNoteContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VideoNoteMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VideoNoteContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VideoNoteMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoNoteContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VideoNoteMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -519,9 +511,9 @@ 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, CommonMessage<VoiceContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, VoiceMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in VoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, VoiceMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,
@@ -543,9 +535,9 @@ 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, CommonMessage<InvoiceContent>, Update> = MessageFilterByChat, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, InvoiceMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in CommonMessage<InvoiceContent>, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in InvoiceMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<InvoiceContent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, InvoiceMessage>
)= onEditedContent( )= onEditedContent(
initialFilter, initialFilter,
subcontextUpdatesFilter, subcontextUpdatesFilter,

View File

@@ -7,8 +7,8 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByCha
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.utils.asBaseSentMessageUpdate import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage import dev.inmo.tgbotapi.extensions.utils.chatEventMessageOrNull
import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
@@ -24,7 +24,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : ChatEvent> BC.on
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<T>> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<T>>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
(it.asBaseSentMessageUpdate() ?.data ?.asChatEventMessage() ?.takeIf { it.chatEvent is T } as? ChatEventMessage<T>) ?.let(::listOfNotNull) (it.baseSentMessageUpdateOrNull() ?.data ?.chatEventMessageOrNull() ?.takeIf { it.chatEvent is T } as? ChatEventMessage<T>) ?.let(::listOfNotNull)
} }
/** /**
@@ -84,86 +84,6 @@ suspend fun <BC : BehaviourContext> BC.onChatEvent(
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<ChatEvent>> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<ChatEvent>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) ) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEvent>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEvent>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEvent>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEvent>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatStartedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatStarted>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatStarted>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatStarted>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatStarted>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatEndedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatEnded>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatEnded>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatEnded>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatEnded>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
@Deprecated("Renamed as Video instead of Voice")
suspend fun <BC : BehaviourContext> BC.onVoiceChatParticipantsInvitedEvent(
initialFilter: SimpleFilter<ChatEventMessage<VideoChatParticipantsInvited>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatEventMessage<VideoChatParticipantsInvited>, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ChatEventMessage<VideoChatParticipantsInvited>, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatEventMessage<VideoChatParticipantsInvited>>
) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
/** /**
* @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,

View File

@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.InlineQueryFilterB
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.ByUserInlineQueryMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserInlineQueryMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asInlineQueryUpdate import dev.inmo.tgbotapi.extensions.utils.inlineQueryUpdateOrNull
import dev.inmo.tgbotapi.types.InlineQueries.query.* import dev.inmo.tgbotapi.types.InlineQueries.query.*
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -15,7 +15,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : InlineQuery> BC.
markerFactory: MarkerFactory<in T, Any> = ByUserInlineQueryMarkerFactory, markerFactory: MarkerFactory<in T, Any> = ByUserInlineQueryMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asInlineQueryUpdate() ?.data as? T) ?.let(::listOfNotNull) (it.inlineQueryUpdateOrNull() ?.data as? T) ?.let(::listOfNotNull)
} }
/** /**

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.* import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptionsAsync
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
@@ -15,16 +15,17 @@ internal suspend inline fun <BC : BehaviourContext, reified T> BC.on(
noinline updateToData: (Update) -> List<T>? noinline updateToData: (Update) -> List<T>?
) = flowsUpdatesFilter.expectFlow(bot) { ) = flowsUpdatesFilter.expectFlow(bot) {
updateToData(it) ?.mapNotNull { data -> updateToData(it) ?.mapNotNull { data ->
if (initialFilter ?.invoke(data) != false) data else null if (initialFilter ?.invoke(data) != false) it to data else null
} ?: emptyList() } ?: emptyList()
}.subscribeSafelyWithoutExceptionsAsync( }.subscribeSafelyWithoutExceptionsAsync(
scope, scope,
markerFactory::invoke { markerFactory(it.second) }
) { triggerData -> ) { (update, triggerData) ->
createSubContextAndDoWithUpdatesFilter( createSubContextAndDoWithUpdatesFilter(
updatesFilter = subcontextUpdatesFilter ?.toOneType(triggerData),
stopOnCompletion = false stopOnCompletion = false
) { ) {
scenarioReceiver(triggerData) if (subcontextUpdatesFilter ?.invoke(this, triggerData, update) != false) {
scenarioReceiver(triggerData)
}
} }
} }

View File

@@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessagesFilterByCh
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.ByChatMediaGroupMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMediaGroupMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate import dev.inmo.tgbotapi.extensions.utils.sentMediaGroupUpdateOrNull
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -20,7 +20,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : MediaGroupConten
markerFactory: MarkerFactory<in List<MediaGroupMessage<T>>, Any> = ByChatMediaGroupMarkerFactory, markerFactory: MarkerFactory<in List<MediaGroupMessage<T>>, Any> = ByChatMediaGroupMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, List<MediaGroupMessage<T>>> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, List<MediaGroupMessage<T>>>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asSentMediaGroupUpdate() ?.data ?.takeIf { messages -> (it.sentMediaGroupUpdateOrNull() ?.data ?.takeIf { messages ->
messages.all { message -> messages.all { message ->
message.content is T message.content is T
} }

View File

@@ -5,8 +5,8 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByCha
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.utils.asMessageUpdate import dev.inmo.tgbotapi.extensions.utils.messageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.asPassportMessage import dev.inmo.tgbotapi.extensions.utils.passportMessageOrNull
import dev.inmo.tgbotapi.types.message.PassportMessage import dev.inmo.tgbotapi.types.message.PassportMessage
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -17,7 +17,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : EncryptedPasspor
markerFactory: MarkerFactory<in PassportMessage, Any> = ByChatMessageMarkerFactory, markerFactory: MarkerFactory<in PassportMessage, Any> = ByChatMessageMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PassportMessage> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PassportMessage>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asMessageUpdate() ?.data ?.asPassportMessage() ?.takeIf { it.passportData.data.any { it is T } }) ?.let(::listOfNotNull) (it.messageUpdateOrNull() ?.data ?.passportMessageOrNull() ?.takeIf { it.passportData.data.any { it is T } }) ?.let(::listOfNotNull)
} }

View File

@@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.*
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.ByIdPollAnswerMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByIdPollAnswerMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asPollAnswerUpdate import dev.inmo.tgbotapi.extensions.utils.pollAnswerUpdateOrNull
import dev.inmo.tgbotapi.types.polls.PollAnswer import dev.inmo.tgbotapi.types.polls.PollAnswer
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -16,7 +16,7 @@ internal suspend inline fun <BC : BehaviourContext> BC.onPollAnswered(
markerFactory: MarkerFactory<in PollAnswer, Any> = ByIdPollAnswerMarkerFactory, markerFactory: MarkerFactory<in PollAnswer, Any> = ByIdPollAnswerMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollAnswer> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollAnswer>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asPollAnswerUpdate() ?.data) ?.let(::listOfNotNull) (it.pollAnswerUpdateOrNull() ?.data) ?.let(::listOfNotNull)
} }
/** /**

View File

@@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.*
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.ByIdPollMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByIdPollMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asPollUpdate import dev.inmo.tgbotapi.extensions.utils.pollUpdateOrNull
import dev.inmo.tgbotapi.types.polls.* import dev.inmo.tgbotapi.types.polls.*
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -16,7 +16,7 @@ internal suspend inline fun <BC : BehaviourContext, reified T : Poll> BC.onPollU
markerFactory: MarkerFactory<in T, Any> = ByIdPollMarkerFactory, markerFactory: MarkerFactory<in T, Any> = ByIdPollMarkerFactory,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T> noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asPollUpdate() ?.data as? T) ?.let(::listOfNotNull) (it.pollUpdateOrNull() ?.data as? T) ?.let(::listOfNotNull)
} }
/** /**

View File

@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.PreCheckoutQueryFi
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.ByUserPreCheckoutQueryMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserPreCheckoutQueryMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asPreCheckoutQueryUpdate import dev.inmo.tgbotapi.extensions.utils.preCheckoutQueryUpdateOrNull
import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -31,5 +31,5 @@ suspend fun <BC : BehaviourContext> BC.onPreCheckoutQuery(
markerFactory: MarkerFactory<in PreCheckoutQuery, Any> = ByUserPreCheckoutQueryMarkerFactory, markerFactory: MarkerFactory<in PreCheckoutQuery, Any> = ByUserPreCheckoutQueryMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PreCheckoutQuery> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PreCheckoutQuery>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asPreCheckoutQueryUpdate() ?.data) ?.let(::listOfNotNull) (it.preCheckoutQueryUpdateOrNull() ?.data) ?.let(::listOfNotNull)
} }

View File

@@ -5,7 +5,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.ShippingQueryFilte
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.ByUserShippingQueryMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserShippingQueryMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.asShippingQueryUpdate import dev.inmo.tgbotapi.extensions.utils.shippingQueryUpdateOrNull
import dev.inmo.tgbotapi.types.payments.ShippingQuery import dev.inmo.tgbotapi.types.payments.ShippingQuery
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
@@ -31,5 +31,5 @@ suspend fun <BC : BehaviourContext> BC.onShippingQuery(
markerFactory: MarkerFactory<in ShippingQuery, Any> = ByUserShippingQueryMarkerFactory, markerFactory: MarkerFactory<in ShippingQuery, Any> = ByUserShippingQueryMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ShippingQuery> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ShippingQuery>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.asShippingQueryUpdate() ?.data) ?.let(::listOfNotNull) (it.shippingQueryUpdateOrNull() ?.data) ?.let(::listOfNotNull)
} }

View File

@@ -2,10 +2,12 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.utils
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitEditedLocation import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitEditedLocationMessage
import dev.inmo.tgbotapi.types.location.* import dev.inmo.tgbotapi.types.location.*
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LiveLocationContent import dev.inmo.tgbotapi.types.message.content.LiveLocationContent
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
/** /**
* Use this extension when you want to follow [LiveLocation] until it will became [StaticLocation]. This method * Use this extension when you want to follow [LiveLocation] until it will became [StaticLocation]. This method
@@ -20,11 +22,7 @@ suspend fun BehaviourContext.followLocation(
onLocation(message.content.location) onLocation(message.content.location)
while (currentLocation !is StaticLocation) { while (currentLocation !is StaticLocation) {
currentLocation = waitEditedLocation( currentLocation = waitEditedLocationMessage().filter { it.messageId == message.messageId && it.chat.id == message.chat.id }.first().content.location
filter = {
it.messageId == message.messageId && it.chat.id == message.chat.id
}
).first().location
onLocation(currentLocation) onLocation(currentLocation)
} }
} }

View File

@@ -1,9 +1,9 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories
import dev.inmo.tgbotapi.types.queries.callback.CallbackQuery
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
import dev.inmo.tgbotapi.types.payments.ShippingQuery import dev.inmo.tgbotapi.types.payments.ShippingQuery
import dev.inmo.tgbotapi.types.queries.callback.CallbackQuery
object ByUserCallbackQueryMarkerFactory : MarkerFactory<CallbackQuery, Any> { object ByUserCallbackQueryMarkerFactory : MarkerFactory<CallbackQuery, Any> {
override suspend fun invoke(data: CallbackQuery) = data.user override suspend fun invoke(data: CallbackQuery) = data.user

View File

@@ -1,107 +1,60 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.google.devtools.ksp"
} }
project.version = "$library_version"
project.group = "$library_group"
project.description = "Core part of tgbotapi with all (and only) required functionality for working with Telegram Bot API" project.description = "Core part of tgbotapi with all (and only) required functionality for working with Telegram Bot API"
apply from: "../publish.gradle" apply from: "$mppProjectWithSerializationPresetPath"
apply from: "$publishGradlePath"
repositories {
mavenLocal()
mavenCentral()
}
kotlin { kotlin {
jvm {
compilations.main {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js(IR) {
browser()
nodejs()
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib') api libs.kotlin.coroutines
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" api libs.kotlin.serialization
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version" api libs.kotlin.serialization.properties
api "org.jetbrains.kotlinx:kotlinx-serialization-properties:$kotlin_serialisation_runtime_version"
api "com.soywiz.korlibs.klock:klock:$korlibs_version" api libs.korlibs.klock
api "com.soywiz.korlibs.krypto:krypto:$korlibs_version" api libs.korlibs.krypto
api "com.benasher44:uuid:$uuid_version" api libs.uuid
api "dev.inmo:micro_utils.coroutines:$micro_utils_version" api libs.microutils.coroutines
api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version" api libs.microutils.serialization.base64
api "dev.inmo:micro_utils.serialization.encapsulator:$micro_utils_version" api libs.microutils.serialization.encapsulator
api "dev.inmo:micro_utils.serialization.typed_serializer:$micro_utils_version" api libs.microutils.serialization.typedSerializer
api "dev.inmo:micro_utils.ktor.common:$micro_utils_version" api libs.microutils.ktor.common
api "dev.inmo:micro_utils.language_codes:$micro_utils_version" api libs.microutils.languageCodes
api "io.ktor:ktor-client-core:$ktor_version" api libs.ktor.client.core
} }
} }
commonTest { commonTest {
dependencies { dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
implementation project(":tgbotapi.utils") implementation project(":tgbotapi.utils")
} }
} }
jvmMain { jvmMain {
dependencies { dependencies {
api "io.ktor:ktor-server:$ktor_version" api libs.ktor.server
api "io.ktor:ktor-server-host-common:$ktor_version" api libs.ktor.server.host.common
api "io.ktor:ktor-client-cio:$ktor_version" api libs.ktor.client.cio
api "javax.activation:activation:$javax_activation_version" api libs.javax.activation
}
}
jvmTest {
dependencies {
implementation kotlin('test-junit')
}
}
jsTest {
dependencies {
implementation kotlin('test-junit')
implementation kotlin('test-js')
}
}
}
targets.all {
compilations.all {
kotlinOptions {
freeCompilerArgs += ["-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi", "-Xopt-in=kotlin.RequiresOptIn"]
} }
} }
} }
} }
java { dependencies {
sourceCompatibility = JavaVersion.VERSION_1_8 add("kspJvm", project(":tgbotapi.ksp"))
targetCompatibility = JavaVersion.VERSION_1_8 }
ksp {
arg("cctargetPackage", "dev.inmo.tgbotapi.extensions.utils")
arg("ccoutputFileName", "ClassCastsNew")
arg("ccoutputFolder", project(":tgbotapi.utils").file("src/commonMain/kotlin").absolutePath)
} }

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("CommonContactData", "dev.inmo.tgbotapi.abstracts.CommonContactData"))
typealias CommonContactData = dev.inmo.tgbotapi.abstracts.CommonContactData

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("CommonSendInvoiceData", "dev.inmo.tgbotapi.abstracts.CommonSendInvoiceData"))
typealias CommonSendInvoiceData = dev.inmo.tgbotapi.abstracts.CommonSendInvoiceData

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("CommonVenueData", "dev.inmo.tgbotapi.abstracts.CommonVenueData"))
typealias CommonVenueData = dev.inmo.tgbotapi.abstracts.CommonVenueData

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("FromUser", "dev.inmo.tgbotapi.abstracts.FromUser"))
typealias FromUser = dev.inmo.tgbotapi.abstracts.FromUser

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("Headed", "dev.inmo.tgbotapi.abstracts.Headed"))
typealias Headed = dev.inmo.tgbotapi.abstracts.Headed

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("HorizontallyAccured", "dev.inmo.tgbotapi.abstracts.HorizontallyAccured"))
typealias HorizontallyAccured = dev.inmo.tgbotapi.abstracts.HorizontallyAccured

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("Livable", "dev.inmo.tgbotapi.abstracts.Livable"))
typealias Livable = dev.inmo.tgbotapi.abstracts.Livable

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("Locationed", "dev.inmo.tgbotapi.abstracts.Locationed"))
typealias Locationed = dev.inmo.tgbotapi.abstracts.Locationed

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("MimeTyped", "dev.inmo.tgbotapi.abstracts.MimeTyped"))
typealias MimeTyped = dev.inmo.tgbotapi.abstracts.MimeTyped

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("Performerable", "dev.inmo.tgbotapi.abstracts.Performerable"))
typealias Performerable = dev.inmo.tgbotapi.abstracts.Performerable

View File

@@ -1,4 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("ProximityAlertable", "dev.inmo.tgbotapi.abstracts.ProximityAlertable"))
typealias ProximityAlertable = dev.inmo.tgbotapi.abstracts.ProximityAlertable

View File

@@ -1,18 +0,0 @@
package dev.inmo.tgbotapi.CommonAbstracts
@Deprecated("Replaced", ReplaceWith("Texted", "dev.inmo.tgbotapi.abstracts.Texted"))
typealias Texted = dev.inmo.tgbotapi.abstracts.Texted
@Deprecated("Replaced", ReplaceWith("TextedWithTextSources", "dev.inmo.tgbotapi.abstracts.TextedWithTextSources"))
typealias TextedWithTextSources = dev.inmo.tgbotapi.abstracts.TextedWithTextSources
@Deprecated("Replaced", ReplaceWith("ParsableOutput", "dev.inmo.tgbotapi.abstracts.ParsableOutput"))
typealias ParsableOutput = dev.inmo.tgbotapi.abstracts.ParsableOutput
@Deprecated("Replaced", ReplaceWith("EntitiesOutput", "dev.inmo.tgbotapi.abstracts.EntitiesOutput"))
typealias EntitiesOutput = dev.inmo.tgbotapi.abstracts.EntitiesOutput
@Deprecated("Replaced", ReplaceWith("TextedOutput", "dev.inmo.tgbotapi.abstracts.TextedOutput"))
typealias TextedOutput = dev.inmo.tgbotapi.abstracts.TextedOutput
@Deprecated("Replaced", ReplaceWith("TextedInput", "dev.inmo.tgbotapi.abstracts.TextedInput"))
typealias TextedInput = dev.inmo.tgbotapi.abstracts.TextedInput

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