1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-12-01 20:05:43 +00:00

Compare commits

..

79 Commits

Author SHA1 Message Date
9fc07f2ff3 fix build 2021-03-12 15:03:11 +06:00
a4bae5133a fill changelog 2021-03-12 14:58:13 +06:00
7bb272f2fa update compatibility note 2021-03-12 14:39:27 +06:00
72cf38d3bb fill Behaviour Builder for ChatMemberUpdated 2021-03-12 14:36:10 +06:00
0adee13cba remove deprecations 2021-03-11 22:28:56 +06:00
f9e3e57f24 migrate 0.32.10 -> 0.33.0 2021-03-11 21:44:08 +06:00
d7d4adc8e4 optimize imports 2021-03-11 21:39:34 +06:00
e9b074a36c updates of FlowsUpdatesFilter 2021-03-11 21:36:29 +06:00
65cba0f014 fill api of chat invite links 2021-03-11 21:25:11 +06:00
36202133a1 update classcasts 2021-03-11 21:06:25 +06:00
66f7801b32 fix ChatInviteLinkRequest 2021-03-11 20:41:47 +06:00
e7265829d1 include ChatMemberUpdated functionality 2021-03-11 20:17:08 +06:00
9ad5bfbc57 remove BotInviteChatLink 2021-03-11 16:36:15 +06:00
aba62ba930 chatmember serializers are public 2021-03-11 16:00:47 +06:00
40d702a311 add representations of all chat invite link functionality 2021-03-10 22:46:56 +06:00
233d893b5a add isOff extension for MessageAutoDeleteTimerChanged 2021-03-09 22:33:05 +06:00
0faca5838c fixes in events builder behaviours 2021-03-09 22:14:16 +06:00
838f62aa84 shortcuts seconds24Hours and seconds7Days are consts for now 2021-03-09 22:06:20 +06:00
bc21a680bc fixes for MessageAutoDeleteTimerChanged 2021-03-09 22:00:17 +06:00
8bb60bea34 now MessageAutoDeleteTimerChanged implementing ChannelEvent and GroupEvent 2021-03-09 21:37:25 +06:00
8daadcff95 now MessageAutoDeleteTimerChanged implementing ChannelEvent and GroupEvent 2021-03-09 21:35:53 +06:00
2a1e624641 VoiceChatParticipantsInvited type now is data class 2021-03-09 20:23:03 +06:00
696822db02 add behaviour builder events updates 2021-03-09 20:04:44 +06:00
ded501d963 remove regular build 2021-03-09 19:52:46 +06:00
86e506c33d include message_auto_delete_timer_change 2021-03-09 19:45:19 +06:00
9902b00e85 include revokeMessages in kickChatMember 2021-03-09 19:33:05 +06:00
53524abcbb include canManageChat 2021-03-09 19:26:30 +06:00
7639b15dc6 voice chats functionality included 2021-03-09 19:19:15 +06:00
61b720c61f fix of content waiters and expecters 2021-03-09 16:54:32 +06:00
baf4c74b69 update micro_utils 2021-03-09 16:46:08 +06:00
367cfff2cb start 0.32.10 2021-03-09 16:45:13 +06:00
75e8d0f62d Merge pull request #325 from InsanusMokrassar/0.32.9
0.32.9
2021-03-05 01:08:58 +06:00
c521a5f9a4 Update CHANGELOG.md 2021-03-03 22:32:44 +06:00
c5513365c2 Update gradle.properties 2021-03-03 22:31:29 +06:00
d184ce7a0f Update mpp_publish_template.kpsb 2021-03-03 01:39:18 +06:00
a3bff3f24d Update publish.gradle 2021-03-03 01:37:38 +06:00
a835b1dcbb Update mpp_publish_template.kpsb 2021-03-03 01:33:50 +06:00
ffed2b80a5 update publish scripts to avoid useless repos 2021-03-02 16:45:13 +06:00
ff24b9f35b add workflow for packages publication 2021-03-02 16:25:55 +06:00
1287852334 update microutils version 2021-03-02 15:26:52 +06:00
fc2f177e38 update dependencies 2021-02-28 22:24:34 +06:00
1efd4dce6e start 0.32.9 2021-02-28 22:21:57 +06:00
69b5a16b17 Update gradle-wrapper.properties 2021-02-23 09:53:45 +06:00
77b531ad06 Merge pull request #307 from InsanusMokrassar/0.32.8
0.32.8
2021-02-22 01:35:40 +06:00
a98d5d9abd update micro_utils 2021-02-21 22:50:47 +06:00
104653ac41 update serialization 2021-02-21 21:15:40 +06:00
63337b8285 start 0.32.8 2021-02-21 21:13:23 +06:00
5cc0bbb31b Merge pull request #303 from InsanusMokrassar/0.32.7
0.32.7
2021-02-18 00:34:46 +06:00
563d784603 RestrictionsChatPermissions 2021-02-18 00:28:36 +06:00
0d9f18f346 DiceAnimationType class casts 2021-02-17 22:29:29 +06:00
23ceaf8e97 LeftRestrictionsChatPermissions 2021-02-17 22:12:58 +06:00
fe2dffd8b5 BehaviourContext updates 2021-02-17 22:11:26 +06:00
eeb46817c3 start 0.32.7 2021-02-17 22:00:46 +06:00
5ab00da31d Merge pull request #300 from InsanusMokrassar/0.32.6
0.32.6
2021-02-17 17:15:40 +06:00
841ae73f7c replyWithDice 2021-02-17 17:10:21 +06:00
41b4d29917 updates in slot machine utils 2021-02-17 16:58:57 +06:00
f8b3c44146 update micro_utils 2021-02-16 13:48:32 +06:00
f0eb670c3f start 0.32.6 2021-02-16 13:47:31 +06:00
fe5d94f31e Update README.md 2021-02-13 10:09:33 +06:00
7901d0a223 Update README.md 2021-02-13 01:42:35 +06:00
799f9123ba Update README.md 2021-02-13 01:38:31 +06:00
f77f010e66 Update README.md 2021-02-11 13:38:55 +06:00
67ddf8d809 Update README.md 2021-02-11 13:37:24 +06:00
81afa46253 Update README.md 2021-02-11 13:36:53 +06:00
a5bba76f07 Update README.md 2021-02-11 13:35:06 +06:00
d882cf9c97 update readme 2021-02-11 12:06:34 +06:00
2e27b8b64d Merge pull request #295 from InsanusMokrassar/0.32.5
0.32.5
2021-02-09 19:13:42 +06:00
4df800eaa9 fix of #291 2021-02-09 19:07:31 +06:00
8d27349868 update content resends and different other things 2021-02-09 18:26:10 +06:00
2a89c41a58 fix of #292 2021-02-09 17:15:28 +06:00
098b5cc393 rewrite createAccumulatedUpdatesRetrieverFlow onto channelFlow 2021-02-09 16:33:48 +06:00
10f4817283 solution of #293 2021-02-08 19:35:32 +06:00
4449893608 fix of #294 2021-02-08 18:15:54 +06:00
3a53f41f66 start 0.32.5 2021-02-08 11:36:20 +06:00
7cd366d893 Update README.md 2021-02-07 18:02:20 +06:00
1309a4111c Merge pull request #290 from InsanusMokrassar/0.32.4
content messages renames
2021-02-07 16:59:51 +06:00
eca0680f2f update readme 2021-02-07 12:44:38 +06:00
d472d371ed Merge pull request #282 from InsanusMokrassar/0.32.4
0.32.4
2021-02-07 12:43:08 +06:00
ff16f9a315 Update README.md 2021-02-05 01:18:38 +06:00
107 changed files with 1447 additions and 716 deletions

View File

@@ -0,0 +1,22 @@
name: Publish package to GitHub Packages
on: [push]
jobs:
publishing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Rewrite version
run: |
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
cat gradle.properties | sed -e "s/^library_version=\([0-9\.]*\)/library_version=\1-branch_$branch-build${{ github.run_number }}/" > gradle.properties.tmp
rm gradle.properties
mv gradle.properties.tmp gradle.properties
- name: Build and publish
run: ./gradlew clean build publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signMetadataPublication
env:
GITHUBPACKAGES_USER: ${{ github.actor }}
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,16 +0,0 @@
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build

View File

@@ -1,5 +1,90 @@
# TelegramBotAPI changelog
## 0.33.0
**UPDATE UP TO Telegram Bot API 5.1**
_**ALL DEPRECATIONS WERE REMOVED**_
* `Common`:
* `Version`:
* `MicroUtils`: `0.4.28` -> `0.4.29`
* `Core`:
* `AdministratorChatMemberSerializer` and `ChatMemberSerializer` has changed their visibility: they are public for now
* Add `ChatInviteLinkRequest` with subrequests like `KnownChatInviteLinkRequest`
* Add `CreateChatInviteLink`/`EditChatInviteLink`/`RevokeChatInviteLink` requests
* Update `KickChatMember` to include `revokeMessages` flag
* Update `PromoteChatMember` to include `canManageVoiceChats` and `canManageChat` flags
* Add `ChatInviteLink` object
* Add `PrimaryInviteLink` for `ChatInviteLink` with `isPrimary == true`
* Add `CommonInviteLink` for `ChatInviteLink` with `isPrimary == false`
* `AdministratorChatMemberSerializer` has been set as public for several versions
* `ChatMemberSerializer` has been set as public for several versions
* Add `ChatMemberUpdated`
* Add `MessageAutoDeleteTimerChanged`
* Add `VoiceChatEvent`
* Add `VoiceChatEnded`
* Add `VoiceChatParticipantsInvited`
* Add `VoiceChatStarted`
* Add `ChatMemberUpdatedUpdate`
* Add `CommonChatMemberUpdatedUpdate`
* Add `MyChatMemberUpdatedUpdate`
* `API`:
* All API extensions has been updated
* `Behaviour Builder`:
* Now content triggers and expectators will wait for channel posts too
* New waiters and triggers for `ChatMemberUpdated` and its variations
## 0.32.9
* `Common`:
* `Version`:
* `Kotlin`: `1.4.30` -> `1.4.31`
* `Ktor`: `1.5.1` -> `1.5.2`
* `MicroUtils`: `0.4.26` -> `0.4.28`
* `Coroutines`: `1.4.2` -> `1.4.3`
## 0.32.8
* `Common`:
* `Version`:
* `Serialization`: `1.1.0-RC` -> `1.1.0`
* `MicroUtils`: `0.4.25` -> `0.4.26`
## 0.32.7
* `Core`:
* New variable `LeftRestrictionsChatPermissions` and `RestrictionsChatPermissions`
* `Extensions Utils`:
* `DiceAnimationType` class casts
* `Behaviour Builder`:
* Now `doInSubContextWithUpdatesFilter` and `doInSubContext` will automatically subscribe on updates of parent
`BehaviourContext`
* `doInSubContextWithFlowsUpdatesFilterSetup`, `doInSubContextWithUpdatesFilter` and `doInSubContext` got new
parameter `stopOnCompletion` to be able to disable stopping of behaviour context on finishing
## 0.32.6
* `Common`:
* `Version`:
* `MicroUtils`: `0.4.24` -> `0.4.25`
* `Extensions API`:
* New extension `TelegramBot#replyWithDice`
* `Extensions Utils`:
* `SlotMachineReelImages` has been renamed to `SlotMachineReelImage`
* `SlotMachineReelImage` got two built-in parameters: `text` and `number`
* New extension `String#asSlotMachineReelImage`
## 0.32.5
* `Core`:
* Add `mention` variants for user ids and receiver variants ([#294](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/294))
* Now `AbstractRequestCallFactory` will set up one-second delay for zero timeouts in `GetUpdate` requests
* Several extensions for `TelegramBotAPI` like `retrieveAccumulatedUpdates` have been added as a solution for
[#293](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/293)
* Links for `tg://user?id=<user_id>` have been updated ([#292](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/292))
* All usages of captions or texts in resends and same things have been replaced with `textSources`
* Global `defaultParseMode` has been added ([#291](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/291))
## 0.32.4
* `Common`:

223
README.md
View File

@@ -1,153 +1,118 @@
[Participate in our common survey ☺](https://forms.gle/q6Xf8K3fD1pPsYUw9)
# TelegramBotAPI
<details>
<summary><b>I do not wanna read a lot, just give me my bot</b></summary>
Hello! This is a set of libraries for working with Telegram Bot API.
You can simply use <a href="https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template">this template</a> (and button
<a href="https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate">Use template</a>) to get your copy of bot and start to code.
<p></p>
<b>P.S. Do not forget to look into our <a href="https://bookstack.inmo.dev/books/telegrambotapi/">minidocs</a> and
<a href="https://tgbotapi.inmo.dev/docs/index.html">kdocs</a></b>
</details>
| Common info | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI.svg?branch=master)](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|
| Common info | [![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://forms.gle/2Hex2ynbHWHhi1KY7)|
| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Useful links | [![Chat in Telegram](badges/chat.svg)](https://t.me/InMoTelegramBotAPI) [![Create bot](badges/template.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![KDocs](badges/kdocs.svg)](https://tgbotapi.inmo.dev/docs/index.html) [Examples](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/), [Mini tutorial](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
| TelegramBotAPI Core status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.core/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.core/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
| TelegramBotAPI API Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api) |
| TelegramBotAPI Util Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils) |
| TelegramBotAPI Behaviour Builder Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.behaviour_builder/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.behaviour_builder/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder) |
| TelegramBotAPI All status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) |
| TelegramBotAPI Core status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
| TelegramBotAPI API Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api) |
| TelegramBotAPI Util Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils) |
| TelegramBotAPI Behaviour Builder Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder) |
| TelegramBotAPI All status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) |
**At the time of publication of version `0.28.0` there are errors in serialization plugins like
[kotlinx.serialization#1004](https://github.com/Kotlin/kotlinx.serialization/issues/1004). It is possible, that both JVM
and JS version may work improperly in some cases with `kotlinx.serialization` version `1.0.0-RC`**
## Examples
## What is it?
There are several things you need to do to launch examples below:
It is a complex of libraries for working with `TelegramBotAPI` in type-safe and strict way as much as it possible. In
the list of this complex currently next projects:
* Add `mavenCentral()` to your project repositories
* [Maven variant](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/Including-in-your-project#pomxml)
* Add dependency `implementation "dev.inmo:tgbotapi:$tgbotapi_version"`
* Replace `tgbotapi_version` with exact version (see last one in the table above) or put variable with this name in project
* Alternative variant for maven [here](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/Including-in-your-project#telegrambotapi)
* [TelegramBotAPI Core](tgbotapi.core/README.md) - core of library. In fact it is independent library and can be used alone
without any additional library
* [TelegramBotAPI API Extensions](tgbotapi.extensions.api/README.md) - contains extensions (mostly for
`RequestsExecutor`), which allows to use the core library in more pleasant way
* [TelegramBotAPI Util Extensions](tgbotapi.extensions.utils/README.md) - contains extensions for more comfortable
work with commands, updates and other different things
* [TelegramBotAPI Behaviour Builder Extensions](tgbotapi.extensions.behaviour_builder/README.md) - builder for
step-by-step handling of bot behaviour in more comfortable manner
* [TelegramBotAPI](tgbotapi/README.md) - concentration of all previously mentioned libraries
More including instructions [available here](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/Including-in-your-project).
Other configuration examples:
Most part of some specific solves or unuseful
moments are describing by official [Telegram Bot API](https://core.telegram.org/bots/api).
* [For multiplatform](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/tree/master/ResenderBot)
* [For JVM](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/blob/master/GetMeBot/build.gradle)
## JavaScript notes
### Most common example
### Versions before `0.28.0`
```kotlin
suspend fun main() {
val bot = telegramBot(TOKEN)
In case if you are want to use this library inside of browser, you will need additional settings (thanks for help to [Alexander Nozik](https://research.jetbrains.org/researchers/altavir)):
<details>
<summary>Gradle build script help (for versions before 0.28.0)</summary>
```groovy
dependencies {
/* ... */
implementation "com.github.insanusmokrassar:TelegramBotAPI:$tgbot_api_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI-extensions-api:$tgbot_api_version" // optional
implementation "com.github.insanusmokrassar:TelegramBotAPI-extensions-utils:$tgbot_api_version" // optional
/* Block of dependencies for correct building in browser */
implementation(npm("fs"))
implementation(npm("bufferutil"))
implementation(npm("utf-8-validate"))
implementation(npm("abort-controller"))
implementation(npm("text-encoding"))
}
/* ... */
kotlin {
target {
browser {
/* Block for fix of exception in absence of some functionality, https://github.com/ktorio/ktor/issues/1339 */
dceTask {
dceOptions {
keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
}
}
}
bot.buildBehaviour {
println(getMe())
onCommand("start") {
reply(it, "Hi:)")
}
}.join()
}
```
</details>
In this example you will see information about this bot at the moment of starting and answer with `Hi:)` every time it
gets message `/start`
## Ok, where should I start?
### Handling only last messages
![Libraries hierarchy](resources/TelegramBotAPI-libraries-hierarchy.svg)
```kotlin
suspend fun main() {
val bot = telegramBot(TOKEN)
In most cases, the most simple way will be to implement [TelegramBotAPI](tgbotapi/README.md) - it contains
all necessary tools for comfort usage of this library. If you want to exclude some libraries, you can implement just
[TelegramBotAPI BehaviourBuilder Extensions](tgbotapi.extensions.behaviour_builder/README.md),
[TelegramBotAPI API Extensions](tgbotapi.extensions.api/README.md),
[TelegramBotAPI Util Extensions](tgbotapi.extensions.utils/README.md) or even
[TelegramBotAPI Core](tgbotapi.core/README.md).
val flowsUpdatesFilter = FlowsUpdatesFilter()
bot.buildBehaviour(flowUpdatesFilter = flowsUpdatesFilter) {
println(getMe())
onCommand("start") {
reply(it, "Hi:)")
}
If you want to dive deeper in the core of library or develop something for it - welcome to learn more from
[TelegramBotAPI Core](tgbotapi.core/README.md) and our [Telegram Chat](https://teleg.one/InMoTelegramBotAPIChat).
Anyway, all libraries are very typical inside of them. Examples:
* In `TelegramBotAPI` common request look like `requestsExecutor.execute(SomeRequest())`
* `tgbotapi.extensions.api` typical syntax look like `requestsExecutor.someRequest()` (in most cases it would be
better to use `bot` name instead of `requestsExecutor`)
* `tgbotapi.extensions.utils` will look like `filter.filterBaseMessageUpdates(chatId).filterExactCommands(Regex("^.*$"))...`
## Build instruction
If you want to build this project or to contribute, there are several recommendations:
### Build
In case if you want to just build project, run next command:
```bash
./gradlew clean build
```
On windows:
```
gradlew.bat clean build
```
### Publishing for work with your version locally
In case, if you want to work in your other projects using your modification (or some state) of this library,
you can use next code:
```bash
./gradlew clean build publishToMavenLocal
```
On windows:
```
gradlew.bat clean build publishToMavenLocal
```
But you must remember, that in this case your local maven repo must be the first one from
your project retrieving libraries:
```groovy
repositories {
mavenLocal() // that must be the first one
jcenter()
mavenCentral()
retrieveAccumulatedUpdates(this).join()
}
}
```
Besides, for your own version you can change variable `library_version` in the file [gradle.properties](./gradle.properties).
The main difference with the previous example is that bot will get only last updates (accumulated before bot launch
and maybe some updates it got after launch)
### Build a little bit more complex behaviour
```kotlin
suspend fun main() {
val bot = telegramBot(TOKEN)
bot.buildBehaviour {
println(getMe())
val nameReplyMarkup = ReplyKeyboardMarkup(
matrix {
row {
+SimpleKeyboardButton("nope")
}
}
)
onCommand("start") {
val photo = waitPhoto(
SendTextMessage(it.chat.id, "Send me your photo please")
).first()
val name = waitText(
SendTextMessage(
it.chat.id,
"Send me your name or choose \"nope\"",
replyMarkup = nameReplyMarkup
)
).first().text.takeIf { it != "nope" }
sendPhoto(
it.chat,
photo.mediaCollection,
entities = buildEntities {
if (name != null) regular(name) // may be collapsed up to name ?.let(::regular)
}
)
}
}.join()
}
```
### More examples
You may find examples in [this project](https://github.com/InsanusMokrassar/TelegramBotAPI-examples). Besides, you are
always welcome in our [wiki](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/About-this-project) and
[chat](https://t.me/InMoTelegramBotAPIChat).

View File

@@ -5,18 +5,18 @@ kotlin.js.generate.externals=true
kotlin.incremental=true
kotlin.incremental.js=true
kotlin_version=1.4.30
kotlin_coroutines_version=1.4.2
kotlin_serialisation_runtime_version=1.1.0-RC
kotlin_version=1.4.31
kotlin_coroutines_version=1.4.3
kotlin_serialisation_runtime_version=1.1.0
klock_version=2.0.6
uuid_version=0.2.3
ktor_version=1.5.1
ktor_version=1.5.2
micro_utils_version=0.4.24
micro_utils_version=0.4.29
javax_activation_version=1.1.1
library_group=dev.inmo
library_version=0.32.4
library_version=0.33.0
github_release_plugin_version=2.2.12

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip

View File

@@ -10,7 +10,7 @@ moments are describing by official [Telegram Bot API](https://core.telegram.org/
## Compatibility
This version compatible with [4th of November 2020 update of TelegramBotAPI (version 5.0)](https://core.telegram.org/bots/api#november-4-2020).
This version compatible with [9th of March 2021 update of TelegramBotAPI (version 5.1)](https://core.telegram.org/bots/api#march-9-2021).
## How to implement library?

View File

@@ -60,6 +60,7 @@ kotlin {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
implementation project(":tgbotapi.extensions.utils")
}
}

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Core","description":"Library for Object-Oriented and type-safe work with Telegram Bot API","url":"https://insanusmokrassar.github.io/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Core","description":"Library for Object-Oriented and type-safe work with Telegram Bot API","url":"https://insanusmokrassar.github.io/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}

View File

@@ -38,28 +38,28 @@ publishing {
}
}
repositories {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/TelegramBotAPI/${project.name}/;publish=1;override=1")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
}
}
}
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}

View File

@@ -16,6 +16,8 @@ import io.ktor.http.ContentType
import kotlinx.serialization.json.Json
import kotlin.collections.set
var defaultUpdateTimeoutForZeroDelay = 1000L
abstract class AbstractRequestCallFactory : KtorCallFactory {
private val methodsCache: MutableMap<String, String> = mutableMapOf()
override suspend fun <T : Any> makeCall(
@@ -41,6 +43,11 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
requestTimeoutMillis = customTimeoutMillis
socketTimeoutMillis = customTimeoutMillis
}
} else {
timeout {
requestTimeoutMillis = defaultUpdateTimeoutForZeroDelay
socketTimeoutMillis = defaultUpdateTimeoutForZeroDelay
}
}
}
}

View File

@@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.requests
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.passport.PassportElementError

View File

@@ -0,0 +1,20 @@
package dev.inmo.tgbotapi.requests.chat.abstracts
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.DeserializationStrategy
interface ChatInviteLinkRequest : SimpleRequest<CommonInviteLink> {
val chatId: ChatIdentifier
override val resultDeserializer: DeserializationStrategy<CommonInviteLink>
get() = CommonInviteLink.serializer()
}
interface KnownChatInviteLinkRequest : ChatInviteLinkRequest {
val inviteLink: String
}
interface EditChatInviteLinkRequest : ChatInviteLinkRequest {
val expireDate: DateTime?
val membersLimit: MembersLimit?
}

View File

@@ -0,0 +1,31 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.requests.chat.abstracts.EditChatInviteLinkRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
@Serializable
data class CreateChatInviteLink(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(expireDateField)
private val expirationUnixTimeStamp: TelegramDate? = null,
@SerialName(memberLimitField)
override val membersLimit: MembersLimit? = null
) : EditChatInviteLinkRequest {
override val expireDate: DateTime?
get() = expirationUnixTimeStamp ?.asDate
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = "createChatInviteLink"
}
fun CreateChatInviteLink(
chatId: ChatId,
expireDate: DateTime,
membersLimit: MembersLimit? = null
): CreateChatInviteLink = CreateChatInviteLink(
chatId, expireDate.toTelegramDate(), membersLimit
)

View File

@@ -0,0 +1,35 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.requests.chat.abstracts.EditChatInviteLinkRequest
import dev.inmo.tgbotapi.requests.chat.abstracts.KnownChatInviteLinkRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
@Serializable
data class EditChatInviteLink(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(inviteLinkField)
override val inviteLink: String,
@SerialName(expireDateField)
private val expirationUnixTimeStamp: TelegramDate? = null,
@SerialName(memberLimitField)
override val membersLimit: MembersLimit? = null
) : EditChatInviteLinkRequest, KnownChatInviteLinkRequest {
override val expireDate: DateTime?
get() = expirationUnixTimeStamp ?.asDate
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = "editChatInviteLink"
}
fun EditChatInviteLink(
chatId: ChatIdentifier,
inviteLink: String,
expireDate: DateTime,
membersLimit: MembersLimit? = null
): EditChatInviteLink = EditChatInviteLink(
chatId, inviteLink, expireDate.toTelegramDate(), membersLimit
)

View File

@@ -0,0 +1,18 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import dev.inmo.tgbotapi.requests.chat.abstracts.KnownChatInviteLinkRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
@Serializable
data class RevokeChatInviteLink(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(inviteLinkField)
override val inviteLink: String
) : KnownChatInviteLinkRequest {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
override fun method(): String = "revokeChatInviteLink"
}

View File

@@ -13,7 +13,9 @@ data class KickChatMember(
@SerialName(userIdField)
override val userId: UserId,
@SerialName(untilDateField)
override val untilDate: TelegramDate? = null
override val untilDate: TelegramDate? = null,
@SerialName(revokeMessagesField)
val revokeMessages: Boolean? = null
) : ChatMemberRequest<Boolean>, UntilDate {
override fun method(): String = "kickChatMember"
override val resultDeserializer: DeserializationStrategy<Boolean>

View File

@@ -31,7 +31,11 @@ data class PromoteChatMember(
@SerialName(canPinMessagesField)
private val canPinMessages: Boolean? = null,
@SerialName(canPromoteMembersField)
private val canPromoteMembers: Boolean? = null
private val canPromoteMembers: Boolean? = null,
@SerialName(canManageVoiceChatsField)
private val canManageVoiceChats: Boolean? = null,
@SerialName(canManageChatField)
private val canManageChat: Boolean? = null
) : ChatMemberRequest<Boolean>, UntilDate {
override fun method(): String = "promoteChatMember"
override val resultDeserializer: DeserializationStrategy<Boolean>

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.requests.send.polls
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types
import dev.inmo.micro_utils.common.Warning
import kotlinx.serialization.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@@ -17,9 +18,20 @@ data class ChatId(
val chatId: Identifier
) : ChatIdentifier()
val ChatId.link: String
get() = "tg://user?id=$chatId"
/**
* https://core.telegram.org/bots/api#formatting-options
*/
@Warning("This API have restrictions in Telegram System")
val Identifier.link: String
get() = "tg://user?id=$this"
/**
* https://core.telegram.org/bots/api#formatting-options
*/
@Warning("This API have restrictions in Telegram System")
val UserId.link: String
get() = chatId.link
val User.link: String
get() = id.link
typealias UserId = ChatId

View File

@@ -0,0 +1,104 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializable
private data class RawChatInviteLink(
@SerialName(inviteLinkField)
val inviteLink: String,
@SerialName(creatorField)
val creator: User,
@SerialName(isPrimaryField)
val isPrimary: Boolean,
@SerialName(isRevokedField)
val isRevoked: Boolean,
@SerialName(expireDateField)
val expirationDateTime: TelegramDate? = null,
@SerialName(memberLimitField)
val membersLimit: MembersLimit ?= null
)
private fun ChatInviteLink.toRawChatInviteLink() = RawChatInviteLink(
inviteLink,
creator,
isPrimary,
isRevoked,
expirationDateTime ?.toTelegramDate(),
membersLimit
)
@Serializable(ChatInviteLinkSerializer::class)
sealed class ChatInviteLink {
abstract val inviteLink: String
abstract val creator: User
abstract val isPrimary: Boolean
abstract val isRevoked: Boolean
abstract val expirationDateTime: DateTime?
abstract val membersLimit: MembersLimit?
}
@Serializable
data class PrimaryInviteLink(
@SerialName(inviteLinkField)
override val inviteLink: String,
@SerialName(creatorField)
override val creator: User,
@SerialName(isRevokedField)
override val isRevoked: Boolean = false,
@SerialName(expireDateField)
private val expireDate: TelegramDate? = null,
@SerialName(memberLimitField)
override val membersLimit: MembersLimit? = null
) : ChatInviteLink() {
override val isPrimary: Boolean
get() = true
override val expirationDateTime: DateTime?
get() = expireDate ?.asDate
}
@Serializable
data class CommonInviteLink(
@SerialName(inviteLinkField)
override val inviteLink: String,
@SerialName(creatorField)
override val creator: User,
@SerialName(isRevokedField)
override val isRevoked: Boolean = false,
@SerialName(expireDateField)
private val expireDate: TelegramDate? = null,
@SerialName(memberLimitField)
override val membersLimit: MembersLimit? = null
) : ChatInviteLink() {
override val isPrimary: Boolean
get() = false
override val expirationDateTime: DateTime?
get() = expireDate ?.asDate
}
@Serializer(ChatInviteLink::class)
object ChatInviteLinkSerializer : KSerializer<ChatInviteLink> {
override val descriptor: SerialDescriptor
get() = RawChatInviteLink.serializer().descriptor
override fun deserialize(decoder: Decoder): ChatInviteLink {
val deserializedRaw = RawChatInviteLink.serializer().deserialize(decoder)
return deserializedRaw.run {
when {
deserializedRaw.isPrimary -> PrimaryInviteLink(
inviteLink, creator, isRevoked, expirationDateTime, membersLimit
)
else -> CommonInviteLink(
inviteLink, creator, isRevoked, expirationDateTime, membersLimit
)
}
}
}
override fun serialize(encoder: Encoder, value: ChatInviteLink) {
RawChatInviteLink.serializer().serialize(encoder, value.toRawChatInviteLink())
}
}

View File

@@ -26,6 +26,10 @@ data class AdministratorChatMemberImpl(
override val canPinMessages: Boolean = false,
@SerialName(canPromoteMembersField)
override val canPromoteMembers: Boolean = false,
@SerialName(canManageVoiceChatsField)
override val canManageVoiceChats: Boolean = false,
@SerialName(canManageChatField)
override val canManageChat: Boolean = false,
@SerialName(isAnonymousField)
override val isAnonymous: Boolean = false,
@SerialName(customTitleField)

View File

@@ -30,6 +30,10 @@ data class CreatorChatMember(
override val canPinMessages: Boolean = true
@Transient
override val canPromoteMembers: Boolean = true
@Transient
override val canManageVoiceChats: Boolean = true
@Transient
override val canManageChat: Boolean = true
@SerialName(statusField)
@Required
private val type: String = "creator"

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types.ChatMember.abstracts
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
@@ -13,12 +14,15 @@ interface AdministratorChatMember : SpecialRightsChatMember {
val canRemoveMessages: Boolean
val canRestrictMembers: Boolean
val canPromoteMembers: Boolean
val canManageVoiceChats: Boolean
val canManageChat: Boolean
val isAnonymous: Boolean
val customTitle: String?
}
@Serializer(AdministratorChatMember::class)
internal object AdministratorChatMemberSerializer : KSerializer<AdministratorChatMember> {
@RiskFeature
object AdministratorChatMemberSerializer : KSerializer<AdministratorChatMember> {
override val descriptor: SerialDescriptor = ChatMemberSerializer.descriptor
override fun deserialize(decoder: Decoder): AdministratorChatMember = ChatMemberSerializer.deserialize(decoder) as AdministratorChatMember

View File

@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.ChatMember.abstracts
import dev.inmo.tgbotapi.types.ChatMember.*
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.statusField
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
@@ -17,7 +18,8 @@ interface ChatMember {
}
@Serializer(ChatMember::class)
internal object ChatMemberSerializer : KSerializer<ChatMember> {
@RiskFeature
object ChatMemberSerializer : KSerializer<ChatMember> {
override val descriptor: SerialDescriptor = JsonObject.serializer().descriptor
override fun deserialize(decoder: Decoder): ChatMember {

View File

@@ -0,0 +1,22 @@
package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ChatMemberUpdated(
@SerialName(chatField)
val chat: Chat,
@SerialName(fromField)
val user: User,
@SerialName(dateField)
val date: TelegramDate,
@SerialName(oldChatMemberField)
val oldChatMemberState: ChatMember,
@SerialName(newChatMemberField)
val newChatMemberState: ChatMember,
@SerialName(inviteLinkField)
val inviteLink: ChatInviteLink? = null
)

View File

@@ -26,10 +26,12 @@ typealias FoursquareId = String
typealias FoursquareType = String
typealias GooglePlaceId = String
typealias GooglePlaceType = String
typealias MembersLimit = Int
typealias Seconds = Int
typealias MilliSeconds = Long
typealias LongSeconds = Long
typealias UnixTimeStamp = LongSeconds
typealias Meters = Float
typealias Degrees = Int
@@ -76,6 +78,8 @@ val explanationLimit = 0 .. 200
val openPeriodPollSecondsLimit = 5 .. 600
val membersLimit = 1 .. 99999
// Made as lazy for correct work in K/JS
val telegramInlineModeGifPermittedMimeTypes by lazy {
listOf(
@@ -162,6 +166,12 @@ const val optionIdsField = "option_ids"
const val ipAddressField = "ip_address"
const val linkedChatIdField = "linked_chat_id"
const val horizontalAccuracyField = "horizontal_accuracy"
const val revokeMessagesField = "revoke_messages"
const val messageAutoDeleteTimeField = "message_auto_delete_time"
const val isPrimaryField = "is_primary"
const val isRevokedField = "is_revoked"
const val expireDateField = "expire_date"
const val memberLimitField = "member_limit"
const val requestContactField = "request_contact"
const val requestLocationField = "request_location"
@@ -239,8 +249,12 @@ const val canInviteUsersField = "can_invite_users"
const val canRestrictMembersField = "can_restrict_members"
const val canPinMessagesField = "can_pin_messages"
const val canPromoteMembersField = "can_promote_members"
const val canManageVoiceChatsField = "can_manage_voice_chats"
const val canManageChatField = "can_manage_chat"
const val pngStickerField = "png_sticker"
const val tgsStickerField = "tgs_sticker"
const val oldChatMemberField = "old_chat_member"
const val newChatMemberField = "new_chat_member"
const val okField = "ok"
const val captionField = "caption"
@@ -292,6 +306,7 @@ const val payField = "pay"
const val permissionsField = "permissions"
const val typeField = "type"
const val valueField = "value"
const val creatorField = "creator"
const val pointField = "point"
const val xShiftField = "x_shift"
@@ -331,6 +346,7 @@ const val telegramPaymentChargeIdField = "telegram_payment_charge_id"
const val providerPaymentChargeIdField = "provider_payment_charge_id"
const val providerTokenField = "provider_token"
const val providerDataField = "provider_data"
const val usersField = "users"
const val requireNameField = "need_name"
const val requirePhoneNumberField = "need_phone_number"

View File

@@ -74,3 +74,15 @@ fun AudioFile.toInputMediaAudio(
title,
thumb ?.fileId
)
fun AudioFile.toInputMediaAudio(
textSources: TextSourcesList = emptyList(),
title: String? = this.title
): InputMediaAudio = InputMediaAudio(
fileId,
textSources,
duration,
performer,
title,
thumb ?.fileId
)

View File

@@ -70,3 +70,11 @@ fun DocumentFile.toInputMediaDocument(
parseMode,
thumb ?.fileId
)
fun DocumentFile.toInputMediaDocument(
textSources: TextSourcesList = emptyList()
) = InputMediaDocument(
fileId,
textSources,
thumb ?.fileId
)

View File

@@ -53,3 +53,10 @@ fun PhotoSize.toInputMediaPhoto(
caption,
parseMode
)
fun PhotoSize.toInputMediaPhoto(
textSources: TextSourcesList = emptyList()
): InputMediaPhoto = InputMediaPhoto(
fileId,
textSources
)

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.internal.*
@@ -21,6 +21,26 @@ data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: List<TextSource>, user: User) = TextMentionTextSource(parts.makeString(), user, parts)
@Suppress("NOTHING_TO_INLINE")
inline fun User.mention(parts: List<TextSource>) = mention(parts, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: List<TextSource>, userId: UserId) = mention(parts, CommonUser(userId, ""))
@Suppress("NOTHING_TO_INLINE")
inline fun UserId.mention(parts: List<TextSource>) = mention(parts, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(parts: List<TextSource>, id: Identifier) = mention(parts, UserId(id))
@Suppress("NOTHING_TO_INLINE")
inline fun Identifier.mention(parts: List<TextSource>) = mention(parts, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(user: User, vararg parts: TextSource) = mention(parts.toList(), user)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(text: String, user: User) = mention(user, regular(text))
@Suppress("NOTHING_TO_INLINE")
inline fun User.mention(text: String) = mention(this, regular(text))
@Suppress("NOTHING_TO_INLINE")
inline fun mention(text: String, userId: UserId) = mention(text, CommonUser(userId, ""))
@Suppress("NOTHING_TO_INLINE")
inline fun UserId.mention(text: String) = mention(text, this)
@Suppress("NOTHING_TO_INLINE")
inline fun mention(text: String, id: Identifier) = mention(text, UserId(id))
@Suppress("NOTHING_TO_INLINE")
inline fun Identifier.mention(text: String) = mention(text, this)

View File

@@ -35,12 +35,21 @@ typealias Markdown = MarkdownParseMode
typealias MarkdownV2 = MarkdownV2ParseMode
typealias HTML = HTMLParseMode
/**
* This variable respects to default parse mode used in places like next:
*
* * [dev.inmo.tgbotapi.types.message.content.TextContent.createResends]
* *
*/
var defaultParseMode: ParseMode = HTML
@Serializer(ParseMode::class)
internal object ParseModeSerializerObject : KSerializer<ParseMode> {
override fun deserialize(decoder: Decoder): ParseMode {
return when (decoder.decodeString()) {
MarkdownParseMode.parseModeName -> MarkdownParseMode
HTMLParseMode.parseModeName -> HTMLParseMode
Markdown.parseModeName -> Markdown
MarkdownV2.parseModeName -> MarkdownV2
HTML.parseModeName -> HTML
else -> throw IllegalArgumentException("Unknown parse mode")
}
}

View File

@@ -11,6 +11,8 @@ const val UPDATE_SHIPPING_QUERY = "shipping_query"
const val UPDATE_PRE_CHECKOUT_QUERY = "pre_checkout_query"
const val UPDATE_POLL = "poll"
const val UPDATE_POLL_ANSWER = "poll_answer"
const val MY_CHAT_MEMBER = "my_chat_member"
const val CHAT_MEMBER = "chat_member"
val ALL_UPDATES_LIST = listOf(
UPDATE_MESSAGE,
@@ -23,5 +25,7 @@ val ALL_UPDATES_LIST = listOf(
UPDATE_SHIPPING_QUERY,
UPDATE_PRE_CHECKOUT_QUERY,
UPDATE_POLL,
UPDATE_POLL_ANSWER
UPDATE_POLL_ANSWER,
MY_CHAT_MEMBER,
CHAT_MEMBER
)

View File

@@ -23,3 +23,25 @@ data class ChatPermissions(
@SerialName(canPinMessagesField)
val canPinMessages: Boolean = false
)
val LeftRestrictionsChatPermissions = ChatPermissions(
canSendMessages = true,
canSendMediaMessages = true,
canSendPolls = true,
canSendOtherMessages = true,
canAddWebPagePreviews = true,
canChangeInfo = true,
canInviteUsers = true,
canPinMessages = true,
)
val RestrictionsChatPermissions = ChatPermissions(
canSendMessages = false,
canSendMediaMessages = false,
canSendPolls = false,
canSendOtherMessages = false,
canAddWebPagePreviews = false,
canChangeInfo = false,
canInviteUsers = false,
canPinMessages = false,
)

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types.files
import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
@@ -44,3 +45,15 @@ inline fun VideoFile.toInputMediaVideo(
duration,
thumb ?.fileId
)
@Suppress("NOTHING_TO_INLINE")
inline fun VideoFile.toInputMediaVideo(
textSources: TextSourcesList
) = InputMediaVideo(
fileId,
textSources,
width,
height,
duration,
thumb ?.fileId
)

View File

@@ -20,5 +20,3 @@ data class ChannelContentMessageImpl<T: MessageContent>(
override val senderBot: CommonBot?,
override val authorSignature: AuthorSignature?
) : ChannelContentMessage<T>
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("ChannelContentMessageImpl", "dev.inmo.tgbotapi.types.message.ChannelContentMessageImpl"))
typealias ChannelMessageImpl<T> = ChannelContentMessageImpl<T>

View File

@@ -0,0 +1,25 @@
package dev.inmo.tgbotapi.types.message.ChatEvents
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.messageAutoDeleteTimeField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
private const val seconds24Hours: Seconds = 60 * 60 * 24
private const val seconds7Days: Seconds = seconds24Hours * 7
@Serializable
data class MessageAutoDeleteTimerChanged(
@SerialName(messageAutoDeleteTimeField)
val newAutoDeleteTime: Seconds // TODO:: check that it is seconds
) : ChannelEvent, GroupEvent, SupergroupEvent
val MessageAutoDeleteTimerChanged.isOff
get() = newAutoDeleteTime == 0
val MessageAutoDeleteTimerChanged.is24Hours
get() = newAutoDeleteTime == seconds24Hours
val MessageAutoDeleteTimerChanged.is7Days
get() = newAutoDeleteTime == seconds7Days

View File

@@ -0,0 +1,3 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts
interface VoiceChatEvent : SupergroupEvent

View File

@@ -0,0 +1,18 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import com.soywiz.klock.TimeSpan
import com.soywiz.klock.seconds
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.durationField
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class VoiceChatEnded(
@SerialName(durationField)
val duration: Seconds
) : VoiceChatEvent {
val timeSpan: TimeSpan
get() = TimeSpan(duration.seconds.milliseconds)
}

View File

@@ -0,0 +1,13 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import dev.inmo.tgbotapi.types.usersField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class VoiceChatParticipantsInvited(
@SerialName(usersField)
val users: List<User> = emptyList()
) : VoiceChatEvent

View File

@@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VoiceChatEvent
import kotlinx.serialization.Serializable
@Serializable
object VoiceChatStarted : VoiceChatEvent

View File

@@ -21,8 +21,6 @@ data class FromChannelGroupContentMessageImpl<T : MessageContent>(
override val senderBot: CommonBot?,
override val authorSignature: AuthorSignature?
) : FromChannelGroupContentMessage<T>
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("FromChannelGroupContentMessageImpl", "dev.inmo.tgbotapi.types.message.FromChannelGroupContentMessageImpl"))
typealias FromChannelGroupMessageImpl<T> = FromChannelGroupContentMessageImpl<T>
data class AnonymousGroupContentMessageImpl<T : MessageContent>(
override val chat: GroupChat,
@@ -36,8 +34,6 @@ data class AnonymousGroupContentMessageImpl<T : MessageContent>(
override val senderBot: CommonBot?,
override val authorSignature: AuthorSignature?
) : AnonymousGroupContentMessage<T>
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("AnonymousGroupContentMessageImpl", "dev.inmo.tgbotapi.types.message.AnonymousGroupContentMessageImpl"))
typealias AnonymousGroupMessageImpl<T> = AnonymousGroupContentMessageImpl<T>
data class CommonGroupContentMessageImpl<T : MessageContent>(
override val chat: GroupChat,
@@ -51,5 +47,3 @@ data class CommonGroupContentMessageImpl<T : MessageContent>(
override val content: T,
override val senderBot: CommonBot?
) : CommonGroupContentMessage<T>
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("CommonGroupContentMessageImpl", "dev.inmo.tgbotapi.types.message.CommonGroupContentMessageImpl"))
typealias CommonGroupMessageImpl<T> = CommonGroupContentMessageImpl<T>

View File

@@ -4,7 +4,8 @@ import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.PrivateContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentInfo
@@ -21,5 +22,3 @@ data class PrivateContentMessageImpl<T: MessageContent>(
override val senderBot: CommonBot?,
val paymentInfo: SuccessfulPaymentInfo?
) : PrivateContentMessage<T>
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("PrivateContentMessageImpl", "dev.inmo.tgbotapi.types.message.PrivateContentMessageImpl"))
typealias PrivateMessageImpl<T> = PrivateContentMessageImpl<T>

View File

@@ -11,6 +11,7 @@ import dev.inmo.tgbotapi.types.games.RawGame
import dev.inmo.tgbotapi.types.location.Location
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.Message
import dev.inmo.tgbotapi.types.message.abstracts.UnknownMessageType
import dev.inmo.tgbotapi.types.message.content.*
@@ -81,6 +82,14 @@ internal data class RawMessage(
private val dice: Dice? = null,
private val successful_payment: SuccessfulPayment? = null,
// Voice Chat Service Messages
private val voice_chat_started: VoiceChatStarted? = null,
private val voice_chat_ended: VoiceChatEnded? = null,
private val voice_chat_participants_invited: VoiceChatParticipantsInvited? = null,
// AutoDelete Message time changed
private val message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? = null,
// login property
private val connected_website: String? = null,
@@ -172,6 +181,10 @@ internal data class RawMessage(
left_chat_member != null -> LeftChatMember(left_chat_member)
new_chat_title != null -> NewChatTitle(new_chat_title)
new_chat_photo != null -> NewChatPhoto(new_chat_photo.toList())
voice_chat_started != null -> voice_chat_started
message_auto_delete_timer_changed != null -> message_auto_delete_timer_changed
voice_chat_ended != null -> voice_chat_ended
voice_chat_participants_invited != null -> voice_chat_participants_invited
delete_chat_photo -> DeleteChatPhoto()
group_chat_created -> GroupChatCreated(
migrate_to_chat_id

View File

@@ -9,5 +9,3 @@ interface ChannelContentMessage<T: MessageContent> : PossiblySentViaBotCommonMes
override val senderChat: ChannelChat
get() = chat
}
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("ChannelContentMessage", "dev.inmo.tgbotapi.types.message.abstracts.ChannelContentMessage"))
typealias ChannelMessage<T> = ChannelContentMessage<T>

View File

@@ -7,8 +7,6 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
interface GroupContentMessage<T : MessageContent> : PublicContentMessage<T> {
override val chat: GroupChat
}
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("GroupContentMessage", "dev.inmo.tgbotapi.types.message.abstracts.GroupContentMessage"))
typealias GroupMessage<T> = GroupContentMessage<T>
interface FromChannelGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage {
@@ -16,16 +14,10 @@ interface FromChannelGroupContentMessage<T : MessageContent> : GroupContentMessa
override val senderChat: ChannelChat
get() = channel
}
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("FromChannelGroupContentMessage", "dev.inmo.tgbotapi.types.message.abstracts.FromChannelGroupContentMessage"))
typealias FromChannelGroupMessage<T> = FromChannelGroupContentMessage<T>
interface AnonymousGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage {
override val senderChat: GroupChat
get() = chat
}
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("AnonymousGroupContentMessage", "dev.inmo.tgbotapi.types.message.abstracts.AnonymousGroupContentMessage"))
typealias AnonymousGroupMessage<T> = AnonymousGroupContentMessage<T>
interface CommonGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, FromUserMessage
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("CommonGroupContentMessage", "dev.inmo.tgbotapi.types.message.abstracts.CommonGroupContentMessage"))
typealias CommonGroupMessage<T> = CommonGroupContentMessage<T>

View File

@@ -4,5 +4,3 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
import dev.inmo.tgbotapi.types.message.content.abstracts.PossiblySentViaBotCommonMessage
interface PrivateContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, FromUserMessage
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("PrivateContentMessage", "dev.inmo.tgbotapi.types.message.abstracts.PrivateContentMessage"))
typealias PrivateMessage<T> = PrivateContentMessage<T>

View File

@@ -7,5 +7,3 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.PossiblySentViaBotCommo
interface PublicContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T> {
override val chat: PublicChat
}
@Deprecated("Renamed due to ambiguity of naming", ReplaceWith("PublicContentMessage", "dev.inmo.tgbotapi.types.message.PublicContentMessage"))
typealias PublicMessage<T> = PublicContentMessage<T>

View File

@@ -1,16 +1,15 @@
package dev.inmo.tgbotapi.types.message.content
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.SendTextMessage
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.*
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.types.ParseMode.defaultParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
import dev.inmo.tgbotapi.utils.internal.*
data class TextContent(
override val text: String,
@@ -24,51 +23,11 @@ data class TextContent(
replyMarkup: KeyboardMarkup?
): Request<ContentMessage<TextContent>> = SendTextMessage(
chatId,
toHtmlTexts().first(),
HTMLParseMode,
textSources,
false,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
override fun createResends(
chatId: ChatIdentifier,
disableNotification: Boolean,
replyToMessageId: MessageIdentifier?,
allowSendingWithoutReply: Boolean?,
replyMarkup: KeyboardMarkup?
): List<Request<ContentMessage<TextContent>>> = createResends(
chatId,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup,
HTMLParseMode
)
fun createResends(
chatId: ChatIdentifier,
disableNotification: Boolean,
replyToMessageId: MessageIdentifier?,
allowSendingWithoutReply: Boolean?,
replyMarkup: KeyboardMarkup?,
parseMode: ParseMode = HTMLParseMode
): List<Request<ContentMessage<TextContent>>> = when (parseMode) {
is MarkdownParseMode -> toMarkdownTexts()
is MarkdownV2ParseMode -> toMarkdownV2Texts()
is HTMLParseMode -> toHtmlTexts()
}.map {
SendTextMessage(
chatId,
it,
parseMode,
false,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
)
}
}

View File

@@ -14,12 +14,4 @@ interface ResendableContent {
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): Request<out Message>
fun createResends(
chatId: ChatIdentifier,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
): List<Request<out Message>> = listOf(createResend(chatId, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup))
}

View File

@@ -1,21 +1,16 @@
package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendAnimation
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAnimation
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.AnimationFile
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Captions
data class AnimationContent(
override val media: AnimationFile,
@@ -33,8 +28,7 @@ data class AnimationContent(
chatId,
media.fileId,
media.thumb ?.fileId,
toHtmlCaptions().firstOrNull(),
HTMLParseMode,
textSources,
media.duration,
media.width,
media.height,
@@ -46,8 +40,7 @@ data class AnimationContent(
override fun asInputMedia(): InputMediaAnimation = InputMediaAnimation(
media.fileId,
toMarkdownV2Captions().firstOrNull(),
MarkdownV2,
textSources,
media.width,
media.height,
media.duration,

View File

@@ -1,18 +1,17 @@
package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendAudio
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaAudio
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.AudioFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.AudioMediaGroupContent
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class AudioContent(
override val media: AudioFile,
@@ -29,8 +28,7 @@ data class AudioContent(
chatId,
media.fileId,
media.thumb ?.fileId,
toHtmlCaptions().firstOrNull(),
HTMLParseMode,
textSources,
media.duration,
media.performer,
media.title,
@@ -42,8 +40,5 @@ data class AudioContent(
override fun toMediaGroupMemberInputMedia(): InputMediaAudio = asInputMedia()
override fun asInputMedia(): InputMediaAudio = media.toInputMediaAudio(
toHtmlCaptions().firstOrNull(),
HTMLParseMode
)
override fun asInputMedia(): InputMediaAudio = media.toInputMediaAudio(textSources)
}

View File

@@ -1,21 +1,18 @@
package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendDocument
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaDocument
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.files.asDocumentFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.DocumentMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class DocumentContent(
override val media: DocumentFile,
@@ -32,8 +29,7 @@ data class DocumentContent(
chatId,
media.fileId,
media.thumb ?.fileId,
toHtmlCaptions().firstOrNull(),
HTMLParseMode,
textSources,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
@@ -42,10 +38,7 @@ data class DocumentContent(
override fun toMediaGroupMemberInputMedia(): InputMediaDocument = asInputMedia()
override fun asInputMedia(): InputMediaDocument = media.toInputMediaDocument(
toHtmlCaptions().firstOrNull(),
HTMLParseMode
)
override fun asInputMedia(): InputMediaDocument = media.toInputMediaDocument(textSources)
}
@Suppress("NOTHING_TO_INLINE")

View File

@@ -1,19 +1,18 @@
package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendPhoto
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.InputMedia.InputMediaPhoto
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaPhoto
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.*
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaCollectionContent
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class PhotoContent(
override val mediaCollection: Photo,
@@ -31,8 +30,7 @@ data class PhotoContent(
): Request<ContentMessage<PhotoContent>> = SendPhoto(
chatId,
media.fileId,
toHtmlCaptions().firstOrNull(),
HTMLParseMode,
textSources,
disableNotification,
replyToMessageId,
allowSendingWithoutReply,
@@ -41,8 +39,5 @@ data class PhotoContent(
override fun toMediaGroupMemberInputMedia(): InputMediaPhoto = asInputMedia()
override fun asInputMedia(): InputMediaPhoto = media.toInputMediaPhoto(
toHtmlCaptions().firstOrNull(),
HTMLParseMode
)
override fun asInputMedia(): InputMediaPhoto = media.toInputMediaPhoto(textSources)
}

View File

@@ -1,18 +1,17 @@
package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.textSources
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendVideo
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.VideoFile
import dev.inmo.tgbotapi.types.files.toInputMediaVideo
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class VideoContent(
override val media: VideoFile,
@@ -29,8 +28,7 @@ data class VideoContent(
chatId,
media.fileId,
media.thumb ?.fileId,
toHtmlCaptions().firstOrNull(),
HTMLParseMode,
textSources,
media.duration,
media.width,
media.height,
@@ -43,8 +41,5 @@ data class VideoContent(
override fun toMediaGroupMemberInputMedia(): InputMediaVideo = asInputMedia()
override fun asInputMedia(): InputMediaVideo = media.toInputMediaVideo(
toHtmlCaptions().firstOrNull(),
HTMLParseMode
)
override fun asInputMedia(): InputMediaVideo = media.toInputMediaVideo(textSources)
}

View File

@@ -1,20 +1,15 @@
package dev.inmo.tgbotapi.types.message.content.media
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.SendVoice
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.VoiceFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Captions
data class VoiceContent(
override val media: VoiceFile,
@@ -30,8 +25,7 @@ data class VoiceContent(
): Request<ContentMessage<VoiceContent>> = SendVoice(
chatId,
media.fileId,
toHtmlCaptions().firstOrNull(),
HTMLParseMode,
textSources,
media.duration,
disableNotification,
replyToMessageId,
@@ -41,8 +35,7 @@ data class VoiceContent(
override fun asInputMedia(): InputMediaAudio = InputMediaAudio(
media.fileId,
toMarkdownV2Captions().firstOrNull(),
MarkdownV2,
textSources,
media.duration
)
}

View File

@@ -3,8 +3,8 @@ package dev.inmo.tgbotapi.types.passport.encrypted
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
import dev.inmo.tgbotapi.types.emailField
import dev.inmo.tgbotapi.types.hashField
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElementWithEmail
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@@ -3,8 +3,8 @@ package dev.inmo.tgbotapi.types.passport.encrypted
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
import dev.inmo.tgbotapi.types.dataField
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElementWithData
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@@ -3,8 +3,8 @@ package dev.inmo.tgbotapi.types.passport.encrypted
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
import dev.inmo.tgbotapi.types.dataField
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElementWithData
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@@ -2,8 +2,8 @@ package dev.inmo.tgbotapi.types.passport.encrypted
import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer
import dev.inmo.tgbotapi.types.hashField
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElementWithPhoneNumber
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash
import dev.inmo.tgbotapi.types.phoneNumberField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@@ -0,0 +1,10 @@
package dev.inmo.tgbotapi.types.update
import dev.inmo.tgbotapi.types.ChatMemberUpdated
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate
data class CommonChatMemberUpdatedUpdate(
override val updateId: UpdateIdentifier,
override val data: ChatMemberUpdated
) : ChatMemberUpdatedUpdate

View File

@@ -0,0 +1,10 @@
package dev.inmo.tgbotapi.types.update
import dev.inmo.tgbotapi.types.ChatMemberUpdated
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate
data class MyChatMemberUpdatedUpdate(
override val updateId: UpdateIdentifier,
override val data: ChatMemberUpdated
) : ChatMemberUpdatedUpdate

View File

@@ -1,9 +1,9 @@
package dev.inmo.tgbotapi.types.update
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.CallbackQuery.RawCallbackQuery
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.RawChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.query.RawInlineQuery
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
import dev.inmo.tgbotapi.types.payments.ShippingQuery
@@ -11,7 +11,6 @@ import dev.inmo.tgbotapi.types.polls.Poll
import dev.inmo.tgbotapi.types.polls.PollAnswer
import dev.inmo.tgbotapi.types.update.abstracts.UnknownUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.types.updateIdField
import kotlinx.serialization.*
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.jsonObject
@@ -34,7 +33,9 @@ internal data class RawUpdate constructor(
private val shipping_query: ShippingQuery? = null,
private val pre_checkout_query: PreCheckoutQuery? = null,
private val poll: Poll? = null,
private val poll_answer: PollAnswer? = null
private val poll_answer: PollAnswer? = null,
private val my_chat_member: ChatMemberUpdated? = null,
private val chat_member: ChatMemberUpdated? = null
) {
private var initedUpdate: Update? = null
/**
@@ -58,6 +59,8 @@ internal data class RawUpdate constructor(
pre_checkout_query != null -> PreCheckoutQueryUpdate(updateId, pre_checkout_query)
poll != null -> PollUpdate(updateId, poll)
poll_answer != null -> PollAnswerUpdate(updateId, poll_answer)
my_chat_member != null -> MyChatMemberUpdatedUpdate(updateId, my_chat_member)
chat_member != null -> CommonChatMemberUpdatedUpdate(updateId, chat_member)
else -> UnknownUpdate(
updateId,
raw.toString(),

View File

@@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.types.update.abstracts
import dev.inmo.tgbotapi.types.ChatMemberUpdated
interface ChatMemberUpdatedUpdate : Update {
override val data: ChatMemberUpdated
}

View File

@@ -28,6 +28,8 @@ interface FlowsUpdatesFilter : UpdatesFilter {
val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate>
val pollFlow: Flow<PollUpdate>
val pollAnswerFlow: Flow<PollAnswerUpdate>
val chatMemberUpdatedFlow: Flow<CommonChatMemberUpdatedUpdate>
val myChatMemberUpdatedFlow: Flow<MyChatMemberUpdatedUpdate>
val unknownUpdateTypeFlow: Flow<UnknownUpdate>
}
@@ -74,5 +76,7 @@ class DefaultFlowsUpdatesFilter(
override val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val pollFlow: Flow<PollUpdate> = allUpdatesFlow.filterIsInstance()
override val pollAnswerFlow: Flow<PollAnswerUpdate> = allUpdatesFlow.filterIsInstance()
override val chatMemberUpdatedFlow: Flow<CommonChatMemberUpdatedUpdate> = allUpdatesFlow.filterIsInstance()
override val myChatMemberUpdatedFlow: Flow<MyChatMemberUpdatedUpdate> = allUpdatesFlow.filterIsInstance()
override val unknownUpdateTypeFlow: Flow<UnknownUpdate> = allUpdatesFlow.filterIsInstance()
}

View File

@@ -35,4 +35,4 @@ const val lowLevelRiskFeatureMessage = "This method is low-level and not recomme
AnnotationTarget.TYPEALIAS,
AnnotationTarget.TYPE_PARAMETER
)
annotation class RiskFeature(val message: String)
annotation class RiskFeature(val message: String = lowLevelRiskFeatureMessage)

View File

@@ -37,8 +37,6 @@ data class StorageFile(
) {
val input: Input
get() = inputSource()
@Deprecated("This method will be fully replaced with input property", ReplaceWith("input"))
fun asInput() = input
}
@Suppress("NOTHING_TO_INLINE")

View File

@@ -1,97 +0,0 @@
package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.ParseMode.*
import dev.inmo.tgbotapi.types.captionLength
import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.textLength
internal fun createFormattedText(
entities: TextSourcesList,
partLength: Int = textLength.last,
mode: ParseMode = MarkdownParseMode
): List<String> {
val texts = mutableListOf<String>()
val textBuilder = StringBuilder(partLength)
for (entity in entities) {
val string = when (mode) {
is MarkdownParseMode -> entity.markdown
is MarkdownV2ParseMode -> entity.markdownV2
is HTMLParseMode -> entity.html
}
if (textBuilder.length + string.length > partLength) {
if (textBuilder.isNotEmpty()) {
texts.add(textBuilder.toString())
textBuilder.clear()
}
val chunked = string.chunked(partLength)
val last = chunked.last()
textBuilder.append(last)
val listToAdd = if (chunked.size > 1) {
chunked.subList(0, chunked.size - 1)
} else {
emptyList()
}
listToAdd.forEach {
texts.add(it)
}
} else {
textBuilder.append(string)
}
}
if (textBuilder.isNotEmpty()) {
texts.add(textBuilder.toString())
textBuilder.clear()
}
return texts
}
internal fun createMarkdownText(
entities: TextSourcesList,
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
internal fun TextSourcesList.toMarkdownTexts(): List<String> = createMarkdownText(
this,
textLength.last
)
internal fun TextContent.toMarkdownTexts(): List<String> = textSources.toMarkdownTexts()
internal fun createMarkdownV2Text(
entities: TextSourcesList,
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, MarkdownV2ParseMode)
internal fun TextSourcesList.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
this,
captionLength.last
)
internal fun CaptionedInput.toMarkdownV2Captions(): List<String> = textSources.toMarkdownV2Captions()
internal fun TextSourcesList.toMarkdownV2Texts(): List<String> = createMarkdownV2Text(
this,
textLength.last
)
internal fun TextContent.toMarkdownV2Texts(): List<String> = textSources.toMarkdownV2Texts()
internal fun createHtmlText(
entities: TextSourcesList,
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
internal fun TextSourcesList.toHtmlCaptions(): List<String> = createHtmlText(
this,
captionLength.last
)
internal fun CaptionedInput.toHtmlCaptions(): List<String> = textSources.toHtmlCaptions()
internal fun TextSourcesList.toHtmlTexts(): List<String> = createHtmlText(
this,
textLength.last
)
internal fun TextContent.toHtmlTexts(): List<String> = textSources.toHtmlTexts()

View File

@@ -1,14 +1,7 @@
package dev.inmo.tgbotapi.utils.passport
import dev.inmo.micro_utils.crypto.SourceBytes
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.DownloadFile
import dev.inmo.tgbotapi.requests.get.GetFile
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedCredentials
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData
import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.json.JsonObject
interface Decryptor {
fun decrypt(data: EncryptedData): SourceBytes

View File

@@ -2,8 +2,8 @@ package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.CommonAbstracts.plus
import dev.inmo.tgbotapi.extensions.utils.formatting.*
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.utils.internal.*
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@@ -1,8 +1,8 @@
package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.justTextSources
import dev.inmo.tgbotapi.utils.internal.toHtmlTexts
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Texts
import dev.inmo.tgbotapi.extensions.utils.formatting.toHtmlTexts
import dev.inmo.tgbotapi.extensions.utils.formatting.toMarkdownV2Texts
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@@ -4,11 +4,10 @@ import dev.inmo.micro_utils.crypto.decodeBase64
import dev.inmo.tgbotapi.types.passport.credentials.DecryptedCredentials
import dev.inmo.tgbotapi.types.passport.credentials.EncryptedCredentials
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import java.security.*
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
private val regexToRemoveFromKey = Regex("(-----(BEGIN|END) ((?:.*? KEY)|CERTIFICATE)-----|[\\s])")

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Extensions for API","description":"API extensions which provide work with RequestsExecutor of TelegramBotAPI almost like it is described in original Telegram Bot API reference","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-api","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Extensions for API","description":"API extensions which provide work with RequestsExecutor of TelegramBotAPI almost like it is described in original Telegram Bot API reference","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-api","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}

View File

@@ -38,28 +38,28 @@ publishing {
}
}
repositories {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/TelegramBotAPI/${project.name}/;publish=1;override=1")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
}
}
}
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}

View File

@@ -0,0 +1,31 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.CreateChatInviteLink
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
suspend fun TelegramBot.createChatInviteLink(
chatId: ChatIdentifier,
expiration: TelegramDate? = null,
membersLimit: MembersLimit? = null
) = execute(CreateChatInviteLink(chatId, expiration, membersLimit))
suspend fun TelegramBot.createChatInviteLink(
chat: PublicChat,
expiration: TelegramDate? = null,
membersLimit: MembersLimit? = null
) = createChatInviteLink(chat.id, expiration, membersLimit)
suspend fun TelegramBot.createChatInviteLink(
chatId: ChatIdentifier,
expiration: DateTime,
membersLimit: MembersLimit? = null
) = createChatInviteLink(chatId, expiration.toTelegramDate(), membersLimit)
suspend fun TelegramBot.createChatInviteLink(
chat: PublicChat,
expiration: DateTime,
membersLimit: MembersLimit? = null
) = createChatInviteLink(chat.id, expiration.toTelegramDate(), membersLimit)

View File

@@ -0,0 +1,63 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.EditChatInviteLink
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
suspend fun TelegramBot.editChatInviteLink(
chatId: ChatIdentifier,
previousLink: String,
expiration: TelegramDate? = null,
membersLimit: MembersLimit? = null
) = execute(EditChatInviteLink(chatId, previousLink, expiration, membersLimit))
suspend fun TelegramBot.editChatInviteLink(
chat: PublicChat,
previousLink: String,
expiration: TelegramDate? = null,
membersLimit: MembersLimit? = null
) = editChatInviteLink(chat.id, previousLink, expiration, membersLimit)
suspend fun TelegramBot.editChatInviteLink(
chatId: ChatIdentifier,
previousLink: String,
expiration: DateTime,
membersLimit: MembersLimit? = null
) = editChatInviteLink(chatId, previousLink, expiration.toTelegramDate(), membersLimit)
suspend fun TelegramBot.editChatInviteLink(
chat: PublicChat,
previousLink: String,
expiration: DateTime,
membersLimit: MembersLimit? = null
) = editChatInviteLink(chat.id, previousLink, expiration.toTelegramDate(), membersLimit)
suspend fun TelegramBot.editChatInviteLink(
chat: ChatIdentifier,
previousLink: ChatInviteLink,
expiration: TelegramDate? = previousLink.expirationDateTime ?.toTelegramDate(),
membersLimit: MembersLimit? = previousLink.membersLimit
) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
suspend fun TelegramBot.editChatInviteLink(
chat: ChatIdentifier,
previousLink: ChatInviteLink,
expiration: DateTime,
membersLimit: MembersLimit? = previousLink.membersLimit
) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
suspend fun TelegramBot.editChatInviteLink(
chat: PublicChat,
previousLink: ChatInviteLink,
expiration: TelegramDate? = previousLink.expirationDateTime ?.toTelegramDate(),
membersLimit: MembersLimit? = previousLink.membersLimit
) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
suspend fun TelegramBot.editChatInviteLink(
chat: PublicChat,
previousLink: ChatInviteLink,
expiration: DateTime,
membersLimit: MembersLimit? = previousLink.membersLimit
) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)

View File

@@ -0,0 +1,27 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.RevokeChatInviteLink
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.ChatInviteLink
import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
suspend fun TelegramBot.revokeChatInviteLink(
chatId: ChatIdentifier,
previousLink: String
) = execute(RevokeChatInviteLink(chatId, previousLink))
suspend fun TelegramBot.revokeChatInviteLink(
chat: PublicChat,
previousLink: String
) = revokeChatInviteLink(chat.id, previousLink)
suspend fun TelegramBot.revokeChatInviteLink(
chatId: ChatIdentifier,
previousLink: ChatInviteLink
) = revokeChatInviteLink(chatId, previousLink.inviteLink)
suspend fun TelegramBot.revokeChatInviteLink(
chat: PublicChat,
previousLink: ChatInviteLink
) = revokeChatInviteLink(chat, previousLink.inviteLink)

View File

@@ -8,23 +8,27 @@ import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
suspend fun TelegramBot.kickChatMember(
chatId: ChatIdentifier,
userId: UserId,
untilDate: TelegramDate? = null
) = execute(KickChatMember(chatId, userId, untilDate))
untilDate: TelegramDate? = null,
revokeMessages: Boolean? = null
) = execute(KickChatMember(chatId, userId, untilDate, revokeMessages))
suspend fun TelegramBot.kickChatMember(
chat: PublicChat,
userId: UserId,
untilDate: TelegramDate? = null
) = kickChatMember(chat.id, userId, untilDate)
untilDate: TelegramDate? = null,
revokeMessages: Boolean? = null
) = kickChatMember(chat.id, userId, untilDate, revokeMessages)
suspend fun TelegramBot.kickChatMember(
chatId: ChatId,
user: User,
untilDate: TelegramDate? = null
) = kickChatMember(chatId, user.id, untilDate)
untilDate: TelegramDate? = null,
revokeMessages: Boolean? = null
) = kickChatMember(chatId, user.id, untilDate, revokeMessages)
suspend fun TelegramBot.kickChatMember(
chat: PublicChat,
user: User,
untilDate: TelegramDate? = null
) = kickChatMember(chat.id, user.id, untilDate)
untilDate: TelegramDate? = null,
revokeMessages: Boolean? = null
) = kickChatMember(chat.id, user.id, untilDate, revokeMessages)

View File

@@ -17,7 +17,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null
canPromoteMembers: Boolean? = null,
canManageVoiceChats: Boolean? = null,
canManageChat: Boolean?
) = execute(
PromoteChatMember(
chatId,
@@ -31,7 +33,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers,
canRestrictMembers,
canPinMessages,
canPromoteMembers
canPromoteMembers,
canManageVoiceChats,
canManageChat
)
)
@@ -47,7 +51,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null
canPromoteMembers: Boolean? = null,
canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? = null
) = promoteChatMember(
chat.id,
userId,
@@ -60,7 +66,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers,
canRestrictMembers,
canPinMessages,
canPromoteMembers
canPromoteMembers,
canManageVoiceChats,
canManageChat
)
suspend fun TelegramBot.promoteChatMember(
@@ -75,7 +83,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null
canPromoteMembers: Boolean? = null,
canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? = null
) = promoteChatMember(
chatId,
user.id,
@@ -88,7 +98,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers,
canRestrictMembers,
canPinMessages,
canPromoteMembers
canPromoteMembers,
canManageVoiceChats,
canManageChat
)
suspend fun TelegramBot.promoteChatMember(
@@ -103,7 +115,9 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers: Boolean? = null,
canRestrictMembers: Boolean? = null,
canPinMessages: Boolean? = null,
canPromoteMembers: Boolean? = null
canPromoteMembers: Boolean? = null,
canManageVoiceChats: Boolean? = null,
canManageChat: Boolean? = null
) = promoteChatMember(
chat.id,
user.id,
@@ -116,5 +130,7 @@ suspend fun TelegramBot.promoteChatMember(
canInviteUsers,
canRestrictMembers,
canPinMessages,
canPromoteMembers
canPromoteMembers,
canManageVoiceChats,
canManageChat
)

View File

@@ -29,10 +29,18 @@ suspend fun TelegramBot.sendDice(
replyMarkup: KeyboardMarkup? = null
) = sendDice(chat.id, animationType, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
suspend inline fun TelegramBot.reply(
suspend inline fun TelegramBot.replyWithDice(
to: Message,
animationType: DiceAnimationType? = null,
disableNotification: Boolean = false,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = sendDice(to.chat, animationType, disableNotification, to.messageId, allowSendingWithoutReply, replyMarkup)
suspend inline fun TelegramBot.reply(
to: Message,
animationType: DiceAnimationType? = null,
disableNotification: Boolean = false,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: KeyboardMarkup? = null
) = replyWithDice(to, animationType, disableNotification, allowSendingWithoutReply, replyMarkup)

View File

@@ -8,7 +8,6 @@ import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
import dev.inmo.tgbotapi.utils.RiskFeature
/**

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Steps Extensions","description":"This extensions project contains tools for simple interaction with chats","url":"https://insanusmokrassar.github.io/TelegramBotAPI/tgbotapi.extensions.steps","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Steps Extensions","description":"This extensions project contains tools for simple interaction with chats","url":"https://insanusmokrassar.github.io/TelegramBotAPI/tgbotapi.extensions.steps","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}

View File

@@ -38,28 +38,28 @@ publishing {
}
}
repositories {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/TelegramBotAPI/${project.name}/;publish=1;override=1")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
}
}
}
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}

View File

@@ -4,6 +4,7 @@ import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.filter
@@ -25,12 +26,15 @@ data class BehaviourContext(
/**
* Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [newFlowsUpdatesFilterSetUp] is provided and
* [CoroutineScope] as new [BehaviourContext.scope]
* [CoroutineScope] as new [BehaviourContext.scope]. You must do all subscription/running of longPolling manually.
*
* @param newFlowsUpdatesFilterSetUp As a parameter receives [FlowsUpdatesFilter] from old [this] [BehaviourContext.flowsUpdatesFilter]
*/
@RiskFeature("It is recommended to use doInSubContextWithUpdatesFilter instead. " +
"This method is low level and should not be used in case you are not pretty sure you need it.")
suspend fun <T> BehaviourContext.doInSubContextWithFlowsUpdatesFilterSetup(
newFlowsUpdatesFilterSetUp: BehaviourContextAndTypeReceiver<Unit, FlowsUpdatesFilter>?,
stopOnCompletion: Boolean = true,
behaviourContextReceiver: BehaviourContextReceiver<T>
) = copy(
flowsUpdatesFilter = FlowsUpdatesFilter(),
@@ -39,7 +43,7 @@ suspend fun <T> BehaviourContext.doInSubContextWithFlowsUpdatesFilterSetup(
newFlowsUpdatesFilterSetUp ?.let {
it.apply { invoke(this@run, this@doInSubContextWithFlowsUpdatesFilterSetup.flowsUpdatesFilter) }
}
behaviourContextReceiver().also { stop() }
behaviourContextReceiver().also { if (stopOnCompletion) stop() }
}
/**
@@ -48,19 +52,24 @@ suspend fun <T> BehaviourContext.doInSubContextWithFlowsUpdatesFilterSetup(
*/
suspend fun <T> BehaviourContext.doInSubContextWithUpdatesFilter(
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?,
stopOnCompletion: Boolean = true,
behaviourContextReceiver: BehaviourContextReceiver<T>
) = doInSubContextWithFlowsUpdatesFilterSetup(
newFlowsUpdatesFilterSetUp = updatesFilter ?.let {
{ oldOne ->
oldOne.allUpdatesFlow.filter { updatesFilter(it) }.subscribeSafelyWithoutExceptions(scope, asUpdateReceiver)
}
} ?: { oldOne ->
oldOne.allUpdatesFlow.subscribeSafelyWithoutExceptions(scope, asUpdateReceiver)
},
stopOnCompletion,
behaviourContextReceiver
)
suspend fun <T> BehaviourContext.doInSubContext(
stopOnCompletion: Boolean = true,
behaviourContextReceiver: BehaviourContextReceiver<T>
) = doInSubContextWithFlowsUpdatesFilterSetup(newFlowsUpdatesFilterSetUp = null, behaviourContextReceiver)
) = doInSubContextWithUpdatesFilter(updatesFilter = null, stopOnCompletion, behaviourContextReceiver)
/**
* This method will cancel ALL subsequent contexts, expectations and waiters

View File

@@ -0,0 +1,65 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.CallbackQuery.CallbackQuery
import dev.inmo.tgbotapi.types.CallbackQuery.DataCallbackQuery
import dev.inmo.tgbotapi.types.ChatMemberUpdated
import dev.inmo.tgbotapi.types.update.CommonChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.types.update.MyChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate
import kotlinx.coroutines.flow.toList
typealias ChatMemberUpdatedMapper<T> = T.() -> T?
private suspend inline fun <reified T : ChatMemberUpdatedUpdate> BehaviourContext.waitChatMemberUpdated(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
noinline mapper: ChatMemberUpdatedMapper<ChatMemberUpdated>
): List<ChatMemberUpdated> = expectFlow(
initRequest,
count,
errorFactory
) {
(it as? T) ?.data.let(::listOfNotNull)
}.toList().toList()
private suspend inline fun <reified T : ChatMemberUpdatedUpdate> BehaviourContext.waitChatMemberUpdatedWithFilter(
count: Int = 1,
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null },
noinline filter: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) : List<ChatMemberUpdated> = waitChatMemberUpdated<T>(
count,
initRequest,
errorFactory
) {
if (filter == null) {
this
} else {
filter(this)
}
}
suspend fun BehaviourContext.waitChatMemberUpdated(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) = waitChatMemberUpdatedWithFilter<ChatMemberUpdatedUpdate>(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitCommonChatMemberUpdated(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) = waitChatMemberUpdatedWithFilter<CommonChatMemberUpdatedUpdate>(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitMyChatMemberUpdated(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: ChatMemberUpdatedMapper<ChatMemberUpdated>? = null
) = waitChatMemberUpdatedWithFilter<MyChatMemberUpdatedUpdate>(count, initRequest, errorFactory, filter)

View File

@@ -31,7 +31,7 @@ private suspend fun <O> BehaviourContext.waitCommonMessage(
(it as CommonMessage<MessageContent>).mapper()
} ?.let { return@expectFlow it }
}
it.asMessageUpdate() ?.data ?.asCommonMessage() ?.mapper().let(::listOfNotNull)
it.asBaseSentMessageUpdate() ?.data ?.asCommonMessage() ?.mapper().let(::listOfNotNull)
}.toList().toList()
private suspend inline fun <reified T : MessageContent> BehaviourContext.waitContent(

View File

@@ -3,11 +3,12 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.asBaseSentMessageUpdate
import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage
import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate
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 kotlinx.coroutines.flow.toList
@@ -23,7 +24,7 @@ private suspend fun <O> BehaviourContext.waitEventMessages(
count,
errorFactory
) {
it.asMessageUpdate() ?.data ?.asChatEventMessage() ?.mapper().let(::listOfNotNull)
it.asBaseSentMessageUpdate() ?.data ?.asChatEventMessage() ?.mapper().let(::listOfNotNull)
}.toList().toList()
@@ -63,6 +64,39 @@ suspend fun BehaviourContext.waitChatEvents(
count: Int = 1,
filter: EventMessageToEventMapper<ChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVoiceChatEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: EventMessageToEventMapper<VoiceChatEvent>? = null
) = waitEvents(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVoiceChatStartedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: EventMessageToEventMapper<VoiceChatStarted>? = null
) = waitEvents(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVoiceChatEndedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: EventMessageToEventMapper<VoiceChatEnded>? = null
) = waitEvents(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: EventMessageToEventMapper<VoiceChatParticipantsInvited>? = null
) = waitEvents(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1,
filter: EventMessageToEventMapper<MessageAutoDeleteTimerChanged>? = null
) = waitEvents(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitCommonEvents(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },

View File

@@ -1,10 +1,8 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate
import dev.inmo.tgbotapi.extensions.utils.asInlineQueryUpdate
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.CallbackQuery.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.query.BaseInlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.query.LocationInlineQuery

View File

@@ -1,7 +1,8 @@
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.extensions.utils.asMessageUpdate
import dev.inmo.tgbotapi.extensions.utils.asPassportMessage
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.PassportMessage
import dev.inmo.tgbotapi.types.passport.PassportData

View File

@@ -4,7 +4,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.types.CallbackQuery.*

View File

@@ -0,0 +1,61 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.utils.asChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.types.ChatMemberUpdated
import dev.inmo.tgbotapi.types.update.CommonChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.types.update.MyChatMemberUpdatedUpdate
import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate
internal suspend inline fun <reified U : ChatMemberUpdatedUpdate> BehaviourContext.onChatMemberUpdatedInternal(
includeFilterByChatInBehaviourSubContext: Boolean = true,
noinline additionalFilter: (suspend (ChatMemberUpdated) -> Boolean)? = null,
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatMemberUpdated>
) = flowsUpdatesFilter.expectFlow(bot) {
(it as? U) ?.data ?.let { chatMemberUpdated ->
if (additionalFilter == null || additionalFilter(chatMemberUpdated)) chatMemberUpdated else null
}.let(::listOfNotNull)
}.subscribeSafelyWithoutExceptions(scope) { triggerChatMemberUpdated ->
doInSubContextWithUpdatesFilter(
updatesFilter = if (includeFilterByChatInBehaviourSubContext) {
{ it.sourceChat() ?.id ?.chatId == triggerChatMemberUpdated.chat.id.chatId }
} else {
null
}
) {
scenarioReceiver(triggerChatMemberUpdated)
}
}
suspend fun BehaviourContext.onChatMemberUpdated(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatMemberUpdated) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatMemberUpdated>
) = onChatMemberUpdatedInternal<ChatMemberUpdatedUpdate>(
includeFilterByChatInBehaviourSubContext,
additionalFilter,
scenarioReceiver
)
suspend fun BehaviourContext.onCommonChatMemberUpdated(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatMemberUpdated) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatMemberUpdated>
) = onChatMemberUpdatedInternal<CommonChatMemberUpdatedUpdate>(
includeFilterByChatInBehaviourSubContext,
additionalFilter,
scenarioReceiver
)
suspend fun BehaviourContext.onMyChatMemberUpdated(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatMemberUpdated) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatMemberUpdated>
) = onChatMemberUpdatedInternal<MyChatMemberUpdatedUpdate>(
includeFilterByChatInBehaviourSubContext,
additionalFilter,
scenarioReceiver
)

View File

@@ -36,7 +36,7 @@ internal suspend inline fun <reified T : MessageContent> BehaviourContext.onCont
return@expectFlow it
}
}
it.asMessageUpdate() ?.data ?.asCommonMessage() ?.let { message ->
it.asBaseSentMessageUpdate() ?.data ?.asCommonMessage() ?.let { message ->
if (message.content is T) {
val adaptedMessage = message as CommonMessage<T>
if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null

View File

@@ -4,10 +4,12 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.asBaseSentMessageUpdate
import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
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
internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
@@ -15,7 +17,7 @@ internal suspend inline fun <reified T : ChatEvent> BehaviourContext.onEvent(
noinline additionalFilter: (suspend (ChatEventMessage<T>) -> Boolean)? = null,
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<T>>
) = flowsUpdatesFilter.expectFlow(bot) {
it.asMessageUpdate() ?.data ?.asChatEventMessage() ?.let { message ->
it.asBaseSentMessageUpdate() ?.data ?.asChatEventMessage() ?.let { message ->
if (message.chatEvent is T) {
val adaptedMessage = message as ChatEventMessage<T>
if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null
@@ -43,6 +45,31 @@ suspend fun BehaviourContext.onChatEvent(
additionalFilter: (suspend (ChatEventMessage<ChatEvent>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<ChatEvent>>
) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVoiceChatEvent(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatEventMessage<VoiceChatEvent>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<VoiceChatEvent>>
) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVoiceChatStartedEvent(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatEventMessage<VoiceChatStarted>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<VoiceChatStarted>>
) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVoiceChatEndedEvent(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatEventMessage<VoiceChatEnded>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<VoiceChatEnded>>
) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVoiceChatParticipantsInvitedEvent(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatEventMessage<VoiceChatParticipantsInvited>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<VoiceChatParticipantsInvited>>
) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onMessageAutoDeleteTimerChangedEvent(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatEventMessage<MessageAutoDeleteTimerChanged>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, ChatEventMessage<MessageAutoDeleteTimerChanged>>
) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onCommonEvent(
includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (ChatEventMessage<CommonEvent>) -> Boolean)? = null,

View File

@@ -5,8 +5,6 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.utils.asInlineQueryUpdate
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.types.CallbackQuery.DataCallbackQuery
import dev.inmo.tgbotapi.types.CallbackQuery.GameShortNameCallbackQuery
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.query.BaseInlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.query.LocationInlineQuery

View File

@@ -5,12 +5,13 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.asSentMediaGroupUpdate
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.*
import dev.inmo.tgbotapi.types.message.content.media.*
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
import dev.inmo.tgbotapi.utils.PreviewFeature
@PreviewFeature

View File

@@ -3,7 +3,8 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate
import dev.inmo.tgbotapi.extensions.utils.asPassportMessage
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.types.message.PassportMessage
import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement

View File

@@ -44,5 +44,23 @@ kotlin {
api project(":tgbotapi.core")
}
}
commonTest {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
}
jvmTest {
dependencies {
implementation kotlin('test-junit')
}
}
jsTest {
dependencies {
implementation kotlin('test-junit')
implementation kotlin('test-js')
}
}
}
}

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Utility Extensions","description":"Util extensions for more useful work with updates and other things","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-utils","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Utility Extensions","description":"Util extensions for more useful work with updates and other things","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-utils","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}

View File

@@ -38,28 +38,28 @@ publishing {
}
}
repositories {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/TelegramBotAPI/${project.name}/;publish=1;override=1")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
}
}
}
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}

View File

@@ -28,10 +28,14 @@ import dev.inmo.tgbotapi.types.buttons.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.*
import dev.inmo.tgbotapi.types.chat.abstracts.*
import dev.inmo.tgbotapi.types.chat.abstracts.extended.*
import dev.inmo.tgbotapi.types.dice.*
import dev.inmo.tgbotapi.types.files.*
import dev.inmo.tgbotapi.types.files.abstracts.*
import dev.inmo.tgbotapi.types.message.*
import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.LeftChatMember
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.message.content.*
import dev.inmo.tgbotapi.types.message.content.abstracts.*
@@ -394,40 +398,24 @@ inline fun SecureValue.asSecureValueWithTranslations(): SecureValueWithTranslati
inline fun SecureValue.requireSecureValueWithTranslations(): SecureValueWithTranslations = this as SecureValueWithTranslations
@PreviewFeature
inline fun Message.asAnonymousGroupContentMessageImpl(): AnonymousGroupContentMessageImpl<MessageContent>? = this as? AnonymousGroupContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("asAnonymousGroupContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.asAnonymousGroupContentMessageImpl"))
inline fun Message.asAnonymousGroupMessageImpl() = asAnonymousGroupContentMessageImpl()
@PreviewFeature
inline fun Message.requireAnonymousGroupContentMessageImpl(): AnonymousGroupContentMessageImpl<MessageContent> = this as AnonymousGroupContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireAnonymousGroupContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.requireAnonymousGroupContentMessageImpl"))
inline fun Message.requireAnonymousGroupMessageImpl() = requireAnonymousGroupContentMessageImpl()
@PreviewFeature
inline fun Message.asChannelContentMessageImpl(): ChannelContentMessageImpl<MessageContent>? = this as? ChannelContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("asChannelContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.asChannelContentMessageImpl"))
inline fun Message.asChannelMessageImpl() = asChannelContentMessageImpl()
@PreviewFeature
inline fun Message.requireChannelContentMessageImpl(): ChannelContentMessageImpl<MessageContent> = this as ChannelContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireChannelContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.requireChannelContentMessageImpl"))
inline fun Message.requireChannelMessageImpl() = requireChannelContentMessageImpl()
@PreviewFeature
inline fun Message.asFromChannelGroupContentMessageImpl(): FromChannelGroupContentMessageImpl<MessageContent>? = this as? FromChannelGroupContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("asFromChannelGroupContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.asFromChannelGroupContentMessageImpl"))
inline fun Message.asFromChannelGroupMessageImpl() = asFromChannelGroupContentMessageImpl()
@PreviewFeature
inline fun Message.requireFromChannelGroupContentMessageImpl(): FromChannelGroupContentMessageImpl<MessageContent> = this as FromChannelGroupContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireFromChannelGroupContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.requireFromChannelGroupContentMessageImpl"))
inline fun Message.requireFromChannelGroupMessageImpl() = requireFromChannelGroupContentMessageImpl()
@PreviewFeature
inline fun Message.asPassportMessage(): PassportMessage? = this as? PassportMessage
@PreviewFeature
inline fun Message.requirePassportMessage(): PassportMessage = this as PassportMessage
@PreviewFeature
inline fun Message.asPrivateContentMessageImpl(): PrivateContentMessageImpl<MessageContent>? = this as? PrivateContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("asPrivateContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.asPrivateContentMessageImpl"))
inline fun Message.asPrivateMessageImpl() = asPrivateContentMessageImpl()
@PreviewFeature
inline fun Message.requirePrivateContentMessageImpl(): PrivateContentMessageImpl<MessageContent> = this as PrivateContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("requirePrivateContentMessageImpl", "dev.inmo.tgbotapi.extensions.utils.requirePrivateContentMessageImpl"))
inline fun Message.requirePrivateMessageImpl() = requirePrivateContentMessageImpl()
@PreviewFeature
inline fun Message.asChannelEventMessage(): ChannelEventMessage<ChannelEvent>? = this as? ChannelEventMessage<ChannelEvent>
@PreviewFeature
@@ -450,32 +438,20 @@ inline fun Message.asCommonSupergroupEventMessage(): CommonSupergroupEventMessag
inline fun Message.requireCommonSupergroupEventMessage(): CommonSupergroupEventMessage<SupergroupEvent> = this as CommonSupergroupEventMessage<SupergroupEvent>
@PreviewFeature
inline fun Message.asAnonymousGroupContentMessage(): AnonymousGroupContentMessage<MessageContent>? = this as? AnonymousGroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("asAnonymousGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.asAnonymousGroupContentMessage"))
inline fun Message.asAnonymousGroupMessage() = asAnonymousGroupContentMessage()
@PreviewFeature
inline fun Message.requireAnonymousGroupContentMessage(): AnonymousGroupContentMessage<MessageContent> = this as AnonymousGroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireAnonymousGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.requireAnonymousGroupContentMessage"))
inline fun Message.requireAnonymousGroupMessage() = requireAnonymousGroupContentMessage()
@PreviewFeature
inline fun Message.asChannelContentMessage(): ChannelContentMessageImpl<MessageContent>? = this as? ChannelContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("asChannelContentMessage", "dev.inmo.tgbotapi.extensions.utils.asChannelContentMessage"))
inline fun Message.asChannelMessage() = asChannelContentMessage()
@PreviewFeature
inline fun Message.requireChannelContentMessage(): ChannelContentMessageImpl<MessageContent> = this as ChannelContentMessageImpl<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireChannelContentMessage", "dev.inmo.tgbotapi.extensions.utils.requireChannelContentMessage"))
inline fun Message.requireChannelMessage() = requireChannelContentMessage()
@PreviewFeature
inline fun Message.asChatEventMessage(): ChatEventMessage<ChatEvent>? = this as? ChatEventMessage<ChatEvent>
@PreviewFeature
inline fun Message.requireChatEventMessage(): ChatEventMessage<ChatEvent> = this as ChatEventMessage<ChatEvent>
@PreviewFeature
inline fun Message.asCommonGroupContentMessage(): CommonGroupContentMessage<MessageContent>? = this as? CommonGroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("asCommonGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.asCommonGroupContentMessage"))
inline fun Message.asCommonGroupMessage() = asCommonGroupContentMessage()
@PreviewFeature
inline fun Message.requireCommonGroupContentMessage(): CommonGroupContentMessage<MessageContent> = this as CommonGroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireCommonGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.requireCommonGroupContentMessage"))
inline fun Message.requireCommonGroupMessage() = requireCommonGroupContentMessage()
@PreviewFeature
inline fun Message.asCommonMessage(): CommonMessage<MessageContent>? = this as? CommonMessage<MessageContent>
@PreviewFeature
@@ -486,24 +462,16 @@ inline fun Message.asContentMessage(): ContentMessage<MessageContent>? = this as
inline fun Message.requireContentMessage(): ContentMessage<MessageContent> = this as ContentMessage<MessageContent>
@PreviewFeature
inline fun Message.asFromChannelGroupContentMessage(): FromChannelGroupContentMessage<MessageContent>? = this as? FromChannelGroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("asFromChannelGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.asFromChannelGroupContentMessage"))
inline fun Message.asFromChannelGroupMessage() = asFromChannelGroupContentMessage()
@PreviewFeature
inline fun Message.requireFromChannelGroupContentMessage(): FromChannelGroupContentMessage<MessageContent> = this as FromChannelGroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireFromChannelGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.requireFromChannelGroupContentMessage"))
inline fun Message.requireFromChannelGroupMessage() = requireFromChannelGroupContentMessage()
@PreviewFeature
inline fun Message.asGroupEventMessage(): GroupEventMessage<GroupEvent>? = this as? GroupEventMessage<GroupEvent>
@PreviewFeature
inline fun Message.requireGroupEventMessage(): GroupEventMessage<GroupEvent> = this as GroupEventMessage<GroupEvent>
@PreviewFeature
inline fun Message.asGroupContentMessage(): GroupContentMessage<MessageContent>? = this as? GroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("asGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.asGroupContentMessage"))
inline fun Message.asGroupMessage() = asGroupContentMessage()
@PreviewFeature
inline fun Message.requireGroupContentMessage(): GroupContentMessage<MessageContent> = this as GroupContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("requireGroupContentMessage", "dev.inmo.tgbotapi.extensions.utils.requireGroupContentMessage"))
inline fun Message.requireGroupMessage() = requireGroupContentMessage()
@PreviewFeature
inline fun Message.asMediaGroupMessage(): MediaGroupMessage<MediaGroupContent>? = this as? MediaGroupMessage<MediaGroupContent>
@PreviewFeature
@@ -522,20 +490,12 @@ inline fun Message.asPossiblyPaymentMessage(): PossiblyPaymentMessage? = this as
inline fun Message.requirePossiblyPaymentMessage(): PossiblyPaymentMessage = this as PossiblyPaymentMessage
@PreviewFeature
inline fun Message.asPrivateContentMessage(): PrivateContentMessage<MessageContent>? = this as? PrivateContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("asPrivateContentMessage", "dev.inmo.tgbotapi.extensions.utils.asPrivateContentMessage"))
inline fun Message.asPrivateMessage() = asPrivateContentMessage()
@PreviewFeature
inline fun Message.requirePrivateContentMessage(): PrivateContentMessage<MessageContent> = this as PrivateContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("requirePrivateContentMessage", "dev.inmo.tgbotapi.extensions.utils.requirePrivateContentMessage"))
inline fun Message.requirePrivateMessage() = requirePrivateContentMessage()
@PreviewFeature
inline fun Message.asPublicContentMessage(): PublicContentMessage<MessageContent>? = this as? PublicContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("asPublicContentMessage", "dev.inmo.tgbotapi.extensions.utils.asPublicContentMessage"))
inline fun Message.asPublicMessage() = asPublicContentMessage()
@PreviewFeature
inline fun Message.requirePublicContentMessage(): PublicContentMessage<MessageContent> = this as PublicContentMessage<MessageContent>
@Deprecated("Renamed", ReplaceWith("requirePublicContentMessage", "dev.inmo.tgbotapi.extensions.utils.requirePublicContentMessage"))
inline fun Message.requirePublicMessage() = requirePublicContentMessage()
@PreviewFeature
inline fun Message.asSignedMessage(): SignedMessage? = this as? SignedMessage
@PreviewFeature
@@ -937,6 +897,18 @@ inline fun Update.asUnknownUpdate(): UnknownUpdate? = this as? UnknownUpdate
@PreviewFeature
inline fun Update.requireUnknownUpdate(): UnknownUpdate = this as UnknownUpdate
@PreviewFeature
inline fun Update.asCommonChatMemberUpdatedUpdate(): CommonChatMemberUpdatedUpdate? = this as? CommonChatMemberUpdatedUpdate
@PreviewFeature
inline fun Update.requireCommonChatMemberUpdatedUpdate(): CommonChatMemberUpdatedUpdate = this as CommonChatMemberUpdatedUpdate
@PreviewFeature
inline fun Update.asMyChatMemberUpdatedUpdate(): MyChatMemberUpdatedUpdate? = this as? MyChatMemberUpdatedUpdate
@PreviewFeature
inline fun Update.requireMyChatMemberUpdatedUpdate(): MyChatMemberUpdatedUpdate = this as MyChatMemberUpdatedUpdate
@PreviewFeature
inline fun Update.asChatMemberUpdatedUpdate(): ChatMemberUpdatedUpdate? = this as? ChatMemberUpdatedUpdate
@PreviewFeature
inline fun Update.requireChatMemberUpdatedUpdate(): ChatMemberUpdatedUpdate = this as ChatMemberUpdatedUpdate
@PreviewFeature
inline fun TelegramMediaFile.asAnimationFile(): AnimationFile? = this as? AnimationFile
@PreviewFeature
inline fun TelegramMediaFile.requireAnimationFile(): AnimationFile = this as AnimationFile
@@ -1216,3 +1188,107 @@ inline fun TextSource.requireURLTextSource(): URLTextSource = this as URLTextSou
inline fun TextSource.asUnderlineTextSource(): UnderlineTextSource? = this as? UnderlineTextSource
@PreviewFeature
inline fun TextSource.requireUnderlineTextSource(): UnderlineTextSource = this as UnderlineTextSource
@PreviewFeature
inline fun DiceAnimationType.asBasketballDiceAnimationType(): BasketballDiceAnimationType? = this as? BasketballDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireBasketballDiceAnimationType(): BasketballDiceAnimationType = this as BasketballDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.asBowlingDiceAnimationType(): BowlingDiceAnimationType? = this as? BowlingDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireBowlingDiceAnimationType(): BowlingDiceAnimationType = this as BowlingDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.asCubeDiceAnimationType(): CubeDiceAnimationType? = this as? CubeDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireCubeDiceAnimationType(): CubeDiceAnimationType = this as CubeDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.asCustomDiceAnimationType(): CustomDiceAnimationType? = this as? CustomDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireCustomDiceAnimationType(): CustomDiceAnimationType = this as CustomDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.asDartsDiceAnimationType(): DartsDiceAnimationType? = this as? DartsDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireDartsDiceAnimationType(): DartsDiceAnimationType = this as DartsDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.asFootballDiceAnimationType(): FootballDiceAnimationType? = this as? FootballDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireFootballDiceAnimationType(): FootballDiceAnimationType = this as FootballDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.asSlotMachineDiceAnimationType(): SlotMachineDiceAnimationType? = this as? SlotMachineDiceAnimationType
@PreviewFeature
inline fun DiceAnimationType.requireSlotMachineDiceAnimationType(): SlotMachineDiceAnimationType = this as SlotMachineDiceAnimationType
@PreviewFeature
inline fun ChatEvent.asChannelChatCreated(): ChannelChatCreated? = this as? ChannelChatCreated
@PreviewFeature
inline fun ChatEvent.requireChannelChatCreated(): ChannelChatCreated = this as ChannelChatCreated
@PreviewFeature
inline fun ChatEvent.asDeleteChatPhoto(): DeleteChatPhoto? = this as? DeleteChatPhoto
@PreviewFeature
inline fun ChatEvent.requireDeleteChatPhoto(): DeleteChatPhoto = this as DeleteChatPhoto
@PreviewFeature
inline fun ChatEvent.asGroupChatCreated(): GroupChatCreated? = this as? GroupChatCreated
@PreviewFeature
inline fun ChatEvent.requireGroupChatCreated(): GroupChatCreated = this as GroupChatCreated
@PreviewFeature
inline fun ChatEvent.asLeftChatMember(): LeftChatMember? = this as? LeftChatMember
@PreviewFeature
inline fun ChatEvent.requireLeftChatMember(): LeftChatMember = this as LeftChatMember
@PreviewFeature
inline fun ChatEvent.asMessageAutoDeleteTimerChanged(): MessageAutoDeleteTimerChanged? = this as? MessageAutoDeleteTimerChanged
@PreviewFeature
inline fun ChatEvent.requireMessageAutoDeleteTimerChanged(): MessageAutoDeleteTimerChanged = this as MessageAutoDeleteTimerChanged
@PreviewFeature
inline fun ChatEvent.asNewChatMembers(): NewChatMembers? = this as? NewChatMembers
@PreviewFeature
inline fun ChatEvent.requireNewChatMembers(): NewChatMembers = this as NewChatMembers
@PreviewFeature
inline fun ChatEvent.asNewChatPhoto(): NewChatPhoto? = this as? NewChatPhoto
@PreviewFeature
inline fun ChatEvent.requireNewChatPhoto(): NewChatPhoto = this as NewChatPhoto
@PreviewFeature
inline fun ChatEvent.asNewChatTitle(): NewChatTitle? = this as? NewChatTitle
@PreviewFeature
inline fun ChatEvent.requireNewChatTitle(): NewChatTitle = this as NewChatTitle
@PreviewFeature
inline fun ChatEvent.asPinnedMessage(): PinnedMessage? = this as? PinnedMessage
@PreviewFeature
inline fun ChatEvent.requirePinnedMessage(): PinnedMessage = this as PinnedMessage
@PreviewFeature
inline fun ChatEvent.asProximityAlertTriggered(): ProximityAlertTriggered? = this as? ProximityAlertTriggered
@PreviewFeature
inline fun ChatEvent.requireProximityAlertTriggered(): ProximityAlertTriggered = this as ProximityAlertTriggered
@PreviewFeature
inline fun ChatEvent.asSupergroupChatCreated(): SupergroupChatCreated? = this as? SupergroupChatCreated
@PreviewFeature
inline fun ChatEvent.requireSupergroupChatCreated(): SupergroupChatCreated = this as SupergroupChatCreated
@PreviewFeature
inline fun ChatEvent.asChannelEvent(): ChannelEvent? = this as? ChannelEvent
@PreviewFeature
inline fun ChatEvent.requireChannelEvent(): ChannelEvent = this as ChannelEvent
@PreviewFeature
inline fun ChatEvent.asCommonEvent(): CommonEvent? = this as? CommonEvent
@PreviewFeature
inline fun ChatEvent.requireCommonEvent(): CommonEvent = this as CommonEvent
@PreviewFeature
inline fun ChatEvent.asGroupEvent(): GroupEvent? = this as? GroupEvent
@PreviewFeature
inline fun ChatEvent.requireGroupEvent(): GroupEvent = this as GroupEvent
@PreviewFeature
inline fun ChatEvent.asSupergroupEvent(): SupergroupEvent? = this as? SupergroupEvent
@PreviewFeature
inline fun ChatEvent.requireSupergroupEvent(): SupergroupEvent = this as SupergroupEvent
@PreviewFeature
inline fun ChatEvent.asVoiceChatEvent(): VoiceChatEvent? = this as? VoiceChatEvent
@PreviewFeature
inline fun ChatEvent.requireVoiceChatEvent(): VoiceChatEvent = this as VoiceChatEvent
@PreviewFeature
inline fun ChatEvent.asVoiceChatEnded(): VoiceChatEnded? = this as? VoiceChatEnded
@PreviewFeature
inline fun ChatEvent.requireVoiceChatEnded(): VoiceChatEnded = this as VoiceChatEnded
@PreviewFeature
inline fun ChatEvent.asVoiceChatParticipantsInvited(): VoiceChatParticipantsInvited? = this as? VoiceChatParticipantsInvited
@PreviewFeature
inline fun ChatEvent.requireVoiceChatParticipantsInvited(): VoiceChatParticipantsInvited = this as VoiceChatParticipantsInvited
@PreviewFeature
inline fun ChatEvent.asVoiceChatStarted(): VoiceChatStarted? = this as? VoiceChatStarted
@PreviewFeature
inline fun ChatEvent.requireVoiceChatStarted(): VoiceChatStarted = this as VoiceChatStarted

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