mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-17 04:20:13 +00:00
Compare commits
141 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a4bf6911c7 | |||
| 73b3daa68b | |||
| 09748615ae | |||
| 2dc8521aed | |||
| 81de59f37c | |||
| fb61a94c5e | |||
| 26fd5e51bf | |||
| c1ab9da4c4 | |||
| 6b414d64b0 | |||
| 5a3edc2b44 | |||
| 6dcdc2ab7f | |||
| a2ae4f71de | |||
| 5d87b86afe | |||
| ef22735894 | |||
| c0ea479fe3 | |||
| 0846e816e9 | |||
| d837c9d605 | |||
| d1993842c3 | |||
| 4e8a9dcff0 | |||
| 10eb15e172 | |||
| 0320da7614 | |||
| 7aa3ff180e | |||
| a882a212c2 | |||
| 1b15748f65 | |||
| 044fe5eadf | |||
| 9453ec37e7 | |||
| 3d0cbc2d2b | |||
| 198b551ebf | |||
| 1452e32293 | |||
| 946b7abcae | |||
| 879943622a | |||
| c0b4b523cf | |||
| 49e6e9cfe3 | |||
| ffadb6355b | |||
| 9cc402b42d | |||
| b9341f89ac | |||
| ac07f44c81 | |||
| 2e53247726 | |||
| e2dddf96a1 | |||
| ce0fceb240 | |||
| 633239961a | |||
| 8b79b15777 | |||
| a28cf5ddff | |||
| 8c2cffc8e3 | |||
| b933361258 | |||
| 383e722d07 | |||
| 3125c2fc1b | |||
| 965b8c3c50 | |||
| 94745ef373 | |||
| aee5ab564b | |||
| c70f0b65dd | |||
| 30e6f68228 | |||
| 00873a255c | |||
| 6bd423dc11 | |||
| c5ada8cea0 | |||
| 0cb3df4d1a | |||
| b22118b400 | |||
| 2006e45b57 | |||
| c091098feb | |||
| 6cf8d47cbf | |||
| 3dc4e9dda4 | |||
| 6407ad1a93 | |||
| f974e5787f | |||
| 28a9bbd310 | |||
| 599d5a51e3 | |||
| 25f8d15a4b | |||
| 66c2cb2d30 | |||
| 74fb448378 | |||
| 3417ec060f | |||
| 4f54a00003 | |||
| 4fb187da30 | |||
| 7637b6f69a | |||
| 9df9af193c | |||
| ba4b4c4b64 | |||
| fa0861b8bc | |||
| 20494e1d4a | |||
| a404008dee | |||
| 881205dd80 | |||
| 2096c44811 | |||
| 1a3da33589 | |||
| be28c9bd5d | |||
| a193ef5fd5 | |||
| 7c43d3aaa5 | |||
| e034afc75c | |||
| 08e3326d1a | |||
| 6dd1825b98 | |||
| bd4eb29fc1 | |||
| 2cc66ef13c | |||
| 9a8175d1c8 | |||
| 25285b2e8a | |||
| bb09f05d7b | |||
| da5e46e59f | |||
| a3f315a73a | |||
| 43583a885a | |||
| ec02257ecd | |||
| 29ee4a9396 | |||
| 2717cb4fc6 | |||
| 1ce2526401 | |||
| 74c480b07e | |||
| 657e9aa770 | |||
| 0d19952ba7 | |||
| f8cccc3e17 | |||
| bc1b7c3f25 | |||
| ec74111a9d | |||
| 2dadeb7eb7 | |||
| 24bd65501b | |||
| 574ca803fa | |||
| 947e3bf34e | |||
| 488158d8fb | |||
| 41bf3c7f0b | |||
| c2032d21cd | |||
| 6650dd9cfe | |||
| af1d6d6f1a | |||
| a5861d659d | |||
| b36f80a6d3 | |||
| 7c4f034a6c | |||
| 3b08bc6dd2 | |||
| ed87c0ad95 | |||
| c8c0fc2ce8 | |||
| 1f40ce1a81 | |||
| b0219389fc | |||
| f6ec82b449 | |||
| 71dac70635 | |||
| 98f68a9e1e | |||
| e7199e7451 | |||
| 33b50c6c68 | |||
| e4ce6f8fc7 | |||
| 8764f18ca8 | |||
| b2fa7fee9d | |||
| 0121e3a104 | |||
| f6e5664632 | |||
| c5b7c4e1f5 | |||
| 53800d49bf | |||
| d83e3eb10a | |||
| 66b4d06064 | |||
| 4fab01b2a2 | |||
| b81086c4bb | |||
| d776071cac | |||
| 5f33d05deb | |||
| 912cc7217c | |||
| 96e00f6e31 |
164
CHANGELOG.md
164
CHANGELOG.md
@@ -1,5 +1,169 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 0.31.1
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.4.16` -> `0.4.18`
|
||||
|
||||
## 0.31.0
|
||||
|
||||
**THIS UPDATE CONTAINS BREAKING CHANGES**
|
||||
|
||||
* `Common`:
|
||||
* **ALL DEPRECATIONS CREATED SINCE 0.30.0 WERE REMOVED**
|
||||
* `Behaviour Builder`:
|
||||
* Extension `TelegramBot#buildBehaviour` have changed its return value: now it is `Job` instead of
|
||||
`FlowsUpdatesFilter`
|
||||
* `Utils`
|
||||
* New extensions `TelegramBot#longPolling` were added as new recommended way to start getting updates via long
|
||||
polling
|
||||
* Old extensions `RequestsExecutor#startGettingFlowsUpdatesByLongPolling` has been deprecated
|
||||
|
||||
## 0.30.13
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.4.15` -> `0.4.16`
|
||||
* `Core`:
|
||||
* New variable `FlowsUpdatesFilter#allUpdatesWithoutMediaGroupsGroupingFlow` which will contains updates without
|
||||
`SentMediaGroupUpdate`
|
||||
* `Utils`:
|
||||
* Extensions for `ResendableContent` has been added
|
||||
* Extensions for `TextSource` has been added
|
||||
* `Behaviour Builder`:
|
||||
* Project has been created :)
|
||||
|
||||
## 0.30.12
|
||||
|
||||
* `Utils`:
|
||||
* Class casts has been added. Now you can write something like `message.asGroupMessage() ?.let { ... }` instead of
|
||||
`(message as? GroupMessage<*>) ?.let { ... }`
|
||||
|
||||
## 0.30.11
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.4.11` -> `0.4.15`
|
||||
* `Klock`: `2.0.1` -> `2.0.3`
|
||||
* `Ktor`: `1.4.3` -> `1.5.0`
|
||||
* `Core`:
|
||||
* All bot actions got functions for short calling, like `recordVideo` for `RecordVideoNote`
|
||||
* All bot actions got class-cast shortcuts
|
||||
|
||||
## 0.30.10
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `Kotlin`: `1.4.20` -> `1.4.21`
|
||||
* `Klock`: `2.0.0` -> `2.0.1`
|
||||
* `Ktor`: `1.4.2` -> `1.4.3`
|
||||
* `MicroUtils`: `0.4.6` -> `0.4.11`
|
||||
* `API Extensions`:
|
||||
* New function `buildBot`
|
||||
|
||||
## 0.30.9
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `UUID`: `0.2.2` -> `0.2.3`
|
||||
* `Coroutines`: `1.4.1` -> `1.4.2`
|
||||
* `MicroUtils`: `0.4.3` -> `0.4.6`
|
||||
* `Core`:
|
||||
* Add `BowlingDiceAnimationType`
|
||||
|
||||
## 0.30.8
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `Kotlin`: `1.4.10` -> `1.4.20`
|
||||
* `Klock`: `1.12.1` -> `2.0.0`
|
||||
* `MicroUtils`: `0.4.1` -> `0.4.3`
|
||||
|
||||
## 0.30.7
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.4.0` -> `0.4.1`
|
||||
* `Core`:
|
||||
* `TelegramAPIUrlsKeeper` will fix ending of host url since this version
|
||||
* New mechanisms in`PowLimiter` and `CommonLimiter` has been added
|
||||
* New builder `KtorRequestsExecutorBuilder`
|
||||
* New function `telegramBot`
|
||||
* `Utils`:
|
||||
* Simple function `telegramBot(TelegramAPIUrlsKeeper)` has been deprecated with replacement by almost the same
|
||||
function in `Core`
|
||||
|
||||
## 0.30.6
|
||||
|
||||
* `Core`
|
||||
* `TextSource` properties has been renamed:
|
||||
* `asMarkdownSource` -> `markdown`
|
||||
* `asMarkdownV2Source` -> `markdownV2`
|
||||
* `asHtmlSource` -> `html`
|
||||
* `PrivateChat` override `id` property with type `UserId`
|
||||
* Several new extensions and functions in links creation:
|
||||
* New function `makeUsernameLink` with parameter `String`
|
||||
* New extension `Username#link` and function `makeLink(Username)`
|
||||
* Function `makeLinkToMessage` now able to get any type of chat
|
||||
* New extension `Message#link`
|
||||
* Old functions `makeLinkToAddStickerSet...` has been deprecated:
|
||||
* `makeLinkToAddStickerSet`
|
||||
* `makeLinkToAddStickerSetInMarkdownV2`
|
||||
* `makeLinkToAddStickerSetInMarkdown`
|
||||
* `makeLinkToAddStickerSetInHtml`
|
||||
|
||||
## 0.30.5
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.3.3` -> `0.4.0`
|
||||
* `Core`:
|
||||
* Mechanism of `ChatMember` serialization has been changed
|
||||
* Since this version any `ChatMember` can be serialized (even outside in case it marked by `@Serializable`)
|
||||
* Since this version any `ChatMember` (included in this project) can be deserialized in common way
|
||||
* `User` property `id` has changed its type: now it is `UserId` (under the hood it is the same as `ChatId`)
|
||||
|
||||
## 0.30.4
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.3.1` -> `0.3.3`
|
||||
* `Core`:
|
||||
* `MultilevelTextSource#textSources` has been safely renamed to `subsources`
|
||||
* `TextContent#fullEntitiesList` has been deprecated
|
||||
* Now `TextContent` implements `TextedInput`
|
||||
* `TextContent#entities` has been deprecated
|
||||
* `GroupEventMessage` now overrides `chatEvent` with type `GroupEvent`
|
||||
* `SupergroupEventMessage` now overrides `chatEvent` with type `SupergroupEvent`
|
||||
* Any `ChatEventMessage` now have generic type of its `chatEvent` (just like messages)
|
||||
* `Utils`:
|
||||
* Old extensions related to chat events are deprecated:
|
||||
* `Flow<ChatEventMessage<*>>#divideBySource`
|
||||
* `Flow<ChatEventMessage<*>>#onlyChannelEvents`
|
||||
* `Flow<ChatEventMessage<*>>#onlyGroupEvents`
|
||||
* `Flow<ChatEventMessage<*>>#onlySupergroupEvents`
|
||||
* A lot of extensions for `Flow<ChatEventMessage>` has been added:
|
||||
* `FlowsUpdatesFilter#events`
|
||||
* `FlowsUpdatesFilter#channelEvents`
|
||||
* `FlowsUpdatesFilter#groupEvents`
|
||||
* `FlowsUpdatesFilter#supergroupEvents`
|
||||
* And a lot of other filters with specific types
|
||||
|
||||
## 0.30.3
|
||||
|
||||
* `Common`:
|
||||
* `Version`:
|
||||
* `MicroUtils`: `0.3.0` -> `0.3.1`
|
||||
* `Core`:
|
||||
* New type of requests exceptions `TooMuchRequestsException`. In fact it will be rare case when you will get this
|
||||
exception
|
||||
* `EmptyLimiter` has been renamed to `ExceptionsOnlyLimiter` and currently will stop requests after
|
||||
`TooMuchRequestsException` happen until retry time is actual
|
||||
* Now `ExceptionsOnlyLimiter` (previously `EmptyLimiter`) is a class
|
||||
* `AbstractRequestCallFactory` currently will not look at the response and wait if it have `RetryAfter` error. New
|
||||
behaviour aimed on delegating of this work to `RequestsLimiter`
|
||||
|
||||
## 0.30.2
|
||||
|
||||
* `Common`:
|
||||
|
||||
18
README.md
18
README.md
@@ -1,17 +1,30 @@
|
||||
# TelegramBotAPI
|
||||
|
||||
<details>
|
||||
<summary><b>I do not wanna read a lot, just give me my bot</b></summary>
|
||||
|
||||
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 | [](https://github.com/KotlinBy/awesome-kotlin) [](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|
|
||||
| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Useful links | [](https://t.me/InMoTelegramBotAPI) [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](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 | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.core/_latestVersion) [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
|
||||
| TelegramBotAPI Extensions status | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/_latestVersion) [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api) |
|
||||
| TelegramBotAPI API Extensions status | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/_latestVersion) [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api) |
|
||||
| TelegramBotAPI Util Extensions status | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/_latestVersion) [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils) |
|
||||
| TelegramBotAPI Behaviour Builder Extensions status | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.behaviour_builder/_latestVersion) [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder) |
|
||||
| TelegramBotAPI All status | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi/_latestVersion) [](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`**
|
||||
|
||||
## What is it?
|
||||
|
||||
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:
|
||||
@@ -22,6 +35,8 @@ the list of this complex currently next projects:
|
||||
`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
|
||||
|
||||
Most part of some specific solves or unuseful
|
||||
@@ -76,6 +91,7 @@ kotlin {
|
||||
|
||||
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).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<minder version="1.11.1">
|
||||
<minder version="1.11.3">
|
||||
<theme name="default" label="Default" index="-1"/>
|
||||
<styles>
|
||||
<style level="0" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||
@@ -14,45 +14,54 @@
|
||||
<style level="9" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||
<style level="10" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||
</styles>
|
||||
<drawarea x="-320.56697591145837" y="-10.028254191080691" scale="0.75"/>
|
||||
<drawarea x="-950.47548925255796" y="-49.650554065281653" scale="0.5"/>
|
||||
<images/>
|
||||
<nodes>
|
||||
<node id="0" posx="748.88964843749955" posy="119.42341613769531" width="472" height="168" side="top" fold="false" treesize="603" layout="Downwards" group="false">
|
||||
<node id="0" posx="1378.798161778599" posy="159.04571601189673" width="472" height="168" side="top" fold="false" treesize="743" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="439" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="764.88964843749955" posy="135.42341613769531" maxwidth="488.96484375">
|
||||
<nodename posx="1394.798161778599" posy="175.04571601189673" maxwidth="488.96484375">
|
||||
<text data="tgbotapi.core Root project with API. It is not recommended to use its requests directly and better to use at least tgbotapi.extensions.api"/>
|
||||
</nodename>
|
||||
<nodenote></nodenote>
|
||||
<nodes>
|
||||
<node id="1" posx="781.88964843749955" posy="387.42341613769531" width="406" height="145" side="bottom" fold="false" treesize="603" color="#68b723" colorroot="true" layout="Downwards" group="false">
|
||||
<node id="1" posx="1411.798161778599" posy="427.04571601189673" width="406" height="145" side="bottom" fold="false" treesize="743" color="#68b723" colorroot="true" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="none" nodewidth="394" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="797.88964843749955" posy="403.42341613769531" maxwidth="419.451171875">
|
||||
<nodename posx="1427.798161778599" posy="443.04571601189673" maxwidth="419.451171875">
|
||||
<text data="TelegramBotAPI extensions Family of projects which are fully based on TelegramBotAPI and extend its functionality"/>
|
||||
</nodename>
|
||||
<nodenote></nodenote>
|
||||
<nodes>
|
||||
<node id="2" posx="683.38964843749955" posy="632.42341613769531" width="296" height="191" side="bottom" fold="false" treesize="296" color="#68b723" colorroot="true" layout="Downwards" group="false">
|
||||
<node id="2" posx="1247.298161778599" posy="672.04571601189673" width="296" height="191" side="bottom" fold="false" treesize="296" color="#68b723" colorroot="true" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="203" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="699.38964843749955" posy="648.42341613769531" maxwidth="295.90315755208337">
|
||||
<nodename posx="1263.298161778599" posy="688.04571601189673" maxwidth="295.90315755208337">
|
||||
<text data="tgbotapi.extensions.api Extensions project for make requests more look like in the Telegram Bot API and give opportunity to use it's easier"/>
|
||||
</nodename>
|
||||
<nodenote></nodenote>
|
||||
</node>
|
||||
<node id="3" posx="979.38964843749955" posy="632.42341613769531" width="307" height="168" side="bottom" fold="false" treesize="307" color="#68b723" colorroot="true" layout="Downwards" group="false">
|
||||
<node id="3" posx="1609.298161778599" posy="672.04571601189673" width="307" height="168" side="bottom" fold="false" treesize="439" color="#68b723" colorroot="true" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="286" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="995.38964843749955" posy="648.42341613769531" maxwidth="299.252197265625">
|
||||
<nodename posx="1625.298161778599" posy="688.04571601189673" maxwidth="299.252197265625">
|
||||
<text data="tgbotapi.extensions.utils Extensions project with utils things which will make easier different operations"/>
|
||||
</nodename>
|
||||
<nodenote></nodenote>
|
||||
<nodes>
|
||||
<node id="4" posx="1543.298161778599" posy="940.04571601189673" width="439" height="122" side="bottom" fold="false" treesize="439" color="#68b723" colorroot="false" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="387" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="1559.298161778599" posy="956.04571601189673" maxwidth="408.97932942708348">
|
||||
<text data="tgbotapi.extensions.behaviour_builder Extension project for building bot behaviour via special dsl"/>
|
||||
</nodename>
|
||||
<nodenote></nodenote>
|
||||
</node>
|
||||
</nodes>
|
||||
</node>
|
||||
</nodes>
|
||||
</node>
|
||||
</nodes>
|
||||
</node>
|
||||
<node id="4" posx="815.52319335937455" posy="948.04447937011719" width="329" height="213" side="top" fold="false" treesize="329" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="388" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="831.52319335937455" posy="964.04447937011719" maxwidth="394.3671875">
|
||||
<text data="tgbotapi Here included all available TelegramBotAPI libraries: * tgbotapi.core * tgbotapi.extensions.api * tgbotapi.extensions.utils">
|
||||
<node id="5" posx="1391.8445078072455" posy="1155.6062730594231" width="461" height="236" side="bottom" fold="false" treesize="461" layout="Downwards" group="false">
|
||||
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="430" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
||||
<nodename posx="1407.8445078072455" posy="1171.6062730594231" maxwidth="453.885498046875">
|
||||
<text data="tgbotapi Here included all available TelegramBotAPI libraries: * tgbotapi.core * tgbotapi.extensions.api * tgbotapi.extensions.utils * tgbotapi.extensions.behaviour_builder">
|
||||
<color>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
@@ -70,6 +79,94 @@
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="67" end="68" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
<range start="84" end="85" extra="rgb(255,0,0)"/>
|
||||
@@ -102,6 +199,90 @@
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="111" end="112" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
<range start="139" end="140" extra="rgb(255,0,0)"/>
|
||||
</color>
|
||||
</text>
|
||||
</nodename>
|
||||
@@ -110,12 +291,17 @@
|
||||
</nodes>
|
||||
<groups/>
|
||||
<connections>
|
||||
<connection from_id="2" to_id="4" drag_x="905.70642089843705" drag_y="891.23394775390625" color="#777777">
|
||||
<connection from_id="2" to_id="5" drag_x="1475.8213347929195" drag_y="1014.8259945356604" color="#777777">
|
||||
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||
<title></title>
|
||||
<note></note>
|
||||
</connection>
|
||||
<connection from_id="3" to_id="4" drag_x="1056.456420898437" drag_y="885.48394775390625" color="#777777">
|
||||
<connection from_id="4" to_id="5" drag_x="1691.5447998046875" drag_y="1107.00439453125" color="#777777">
|
||||
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||
<title></title>
|
||||
<note></note>
|
||||
</connection>
|
||||
<connection from_id="3" to_id="5" drag_x="1483.48876953125" drag_y="896.18115234375">
|
||||
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||
<title></title>
|
||||
<note></note>
|
||||
|
||||
@@ -9,7 +9,6 @@ buildscript {
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradle_bintray_plugin_version"
|
||||
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dokka_version=1.4.0
|
||||
dokka_version=1.4.20
|
||||
|
||||
org.gradle.jvmargs=-Xmx1024m
|
||||
|
||||
@@ -5,19 +5,18 @@ kotlin.js.generate.externals=true
|
||||
kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
kotlin_version=1.4.10
|
||||
kotlin_coroutines_version=1.4.1
|
||||
kotlin_version=1.4.21
|
||||
kotlin_coroutines_version=1.4.2
|
||||
kotlin_serialisation_runtime_version=1.0.1
|
||||
klock_version=1.12.1
|
||||
uuid_version=0.2.2
|
||||
ktor_version=1.4.2
|
||||
klock_version=2.0.3
|
||||
uuid_version=0.2.3
|
||||
ktor_version=1.5.0
|
||||
|
||||
micro_utils_version=0.3.0
|
||||
micro_utils_version=0.4.18
|
||||
|
||||
javax_activation_version=1.1.1
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=0.30.2
|
||||
library_version=0.31.1
|
||||
|
||||
gradle_bintray_plugin_version=1.8.5
|
||||
github_release_plugin_version=2.2.12
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 89 KiB |
@@ -8,5 +8,6 @@ pluginManagement {
|
||||
include ":tgbotapi.core"
|
||||
include ":tgbotapi.extensions.api"
|
||||
include ":tgbotapi.extensions.utils"
|
||||
include ":tgbotapi.extensions.behaviour_builder"
|
||||
include ":tgbotapi"
|
||||
include ":docs"
|
||||
|
||||
@@ -8,7 +8,6 @@ buildscript {
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradle_bintray_plugin_version"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +47,7 @@ kotlin {
|
||||
api "com.benasher44:uuid:$uuid_version"
|
||||
|
||||
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
|
||||
api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version"
|
||||
|
||||
api "io.ktor:ktor-client-core:$ktor_version"
|
||||
}
|
||||
|
||||
@@ -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","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
|
||||
{"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,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}
|
||||
@@ -1,59 +1,75 @@
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
apply from: "maven.publish.gradle"
|
||||
|
||||
bintray {
|
||||
user = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
|
||||
key = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
|
||||
filesSpec {
|
||||
from "${buildDir}/publications/"
|
||||
eachFile {
|
||||
String directorySubname = it.getFile().parentFile.name
|
||||
if (it.getName() == "module.json") {
|
||||
if (directorySubname == "kotlinMultiplatform") {
|
||||
it.setPath("${project.name}/${project.version}/${project.name}-${project.version}.module")
|
||||
} else {
|
||||
it.setPath("${project.name}-${directorySubname}/${project.version}/${project.name}-${directorySubname}-${project.version}.module")
|
||||
}
|
||||
} else {
|
||||
if (directorySubname == "kotlinMultiplatform" && it.getName() == "pom-default.xml") {
|
||||
it.setPath("${project.name}/${project.version}/${project.name}-${project.version}.pom")
|
||||
} else {
|
||||
it.exclude()
|
||||
}
|
||||
}
|
||||
}
|
||||
into "${project.group}".replace(".", "/")
|
||||
}
|
||||
|
||||
publish = true
|
||||
override = true
|
||||
|
||||
pkg {
|
||||
repo = "TelegramBotAPI"
|
||||
name = "${project.name}"
|
||||
vcsUrl = "https://github.com/InsanusMokrassar/TelegramBotAPI"
|
||||
licenses = ["Apache-2.0"]
|
||||
version {
|
||||
name = "${project.version}"
|
||||
released = new Date()
|
||||
vcsTag = "${project.version}"
|
||||
gpg {
|
||||
sign = true
|
||||
passphrase = project.hasProperty('signing.gnupg.passphrase') ? project.property('signing.gnupg.passphrase') : System.getenv('signing.gnupg.passphrase')
|
||||
}
|
||||
}
|
||||
}
|
||||
task javadocsJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
}
|
||||
task sourceJar (type : Jar) {
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
bintrayUpload.doFirst {
|
||||
publications = publishing.publications.collect {
|
||||
afterEvaluate {
|
||||
project.publishing.publications.all {
|
||||
// rename artifacts
|
||||
groupId "${project.group}"
|
||||
if (it.name.contains('kotlinMultiplatform')) {
|
||||
null
|
||||
artifactId = "${project.name}"
|
||||
artifact sourceJar
|
||||
} else {
|
||||
it.name
|
||||
artifactId = "${project.name}-$name"
|
||||
}
|
||||
} - null
|
||||
}
|
||||
}
|
||||
|
||||
bintrayUpload.dependsOn publishToMavenLocal
|
||||
publishing {
|
||||
publications.all {
|
||||
artifact javadocsJar
|
||||
|
||||
pom {
|
||||
description = "Library for Object-Oriented and type-safe work with Telegram Bot API"
|
||||
name = "Telegram Bot API Core"
|
||||
url = "https://insanusmokrassar.github.io/TelegramBotAPI"
|
||||
|
||||
scm {
|
||||
developerConnection = "scm:git:[fetch=]https://github.com/insanusmokrassar/TelegramBotAPI.git[push=]https://github.com/insanusmokrassar/TelegramBotAPI.git"
|
||||
url = "https://github.com/insanusmokrassar/TelegramBotAPI.git"
|
||||
}
|
||||
|
||||
developers {
|
||||
|
||||
developer {
|
||||
id = "InsanusMokrassar"
|
||||
name = "Ovsiannikov Aleksei"
|
||||
email = "ovsyannikov.alexey95@gmail.com"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
licenses {
|
||||
|
||||
license {
|
||||
name = "Apache Software License 2.0"
|
||||
url = "https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
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')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
publishing.publications.forEach { sign it }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.inmo.tgbotapi.CommonAbstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
|
||||
|
||||
interface Captioned {
|
||||
val caption: String?
|
||||
@@ -13,8 +12,7 @@ interface CaptionedOutput : Captioned {
|
||||
|
||||
interface CaptionedInput : Captioned {
|
||||
/**
|
||||
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
* @see [CaptionedInput.fullEntitiesList]
|
||||
* Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
*/
|
||||
val captionEntities: List<TextPart>
|
||||
}
|
||||
@@ -25,10 +23,3 @@ interface CaptionedInput : Captioned {
|
||||
*/
|
||||
val CaptionedInput.textSources
|
||||
get() = captionEntities.justTextSources()
|
||||
|
||||
/**
|
||||
* Convert its [CaptionedInput.captionEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
|
||||
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
*/
|
||||
@Deprecated("Currently list of entities already full. This method is redundant")
|
||||
fun CaptionedInput.fullEntitiesList(): TextSourcesList = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.inmo.tgbotapi.CommonAbstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
|
||||
|
||||
interface Explained {
|
||||
val explanation: String?
|
||||
@@ -19,8 +18,7 @@ interface ExplainedOutput : ParsableExplainedOutput, EntitiesExplainedOutput
|
||||
|
||||
interface ExplainedInput : Explained {
|
||||
/**
|
||||
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
* @see [ExplainedInput.fullEntitiesList]
|
||||
* Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
*/
|
||||
val explanationEntities: List<TextPart>
|
||||
}
|
||||
@@ -31,10 +29,3 @@ interface ExplainedInput : Explained {
|
||||
*/
|
||||
val ExplainedInput.textSources
|
||||
get() = explanationEntities.justTextSources()
|
||||
|
||||
/**
|
||||
* Convert its [ExplainedInput.explanationEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
|
||||
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
*/
|
||||
@Deprecated("Currently list of entities already full. This method is redundant")
|
||||
fun ExplainedInput.fullEntitiesList(): TextSourcesList = explanation ?.fullListOfSubSource(explanationEntities) ?.map { it.source } ?: emptyList()
|
||||
|
||||
@@ -8,15 +8,11 @@ import dev.inmo.tgbotapi.types.textLength
|
||||
const val DirectInvocationOfTextSourceConstructor = "It is strongly not recommended to use constructors directly instead of factory methods"
|
||||
|
||||
typealias TextSourcesList = List<TextSource>
|
||||
@Deprecated("All lists of TextSource in public API now are full. So, this typealias is redundant")
|
||||
typealias FullTextSourcesList = List<TextSource>
|
||||
@Deprecated("All lists of TextPart in public API now are full. So, this typealias is redundant")
|
||||
typealias FullTextPartsList = List<TextPart>
|
||||
|
||||
interface TextSource {
|
||||
val asMarkdownSource: String
|
||||
val asMarkdownV2Source: String
|
||||
val asHtmlSource: String
|
||||
val markdown: String
|
||||
val markdownV2: String
|
||||
val html: String
|
||||
val source: String
|
||||
|
||||
val asText: String
|
||||
@@ -33,10 +29,7 @@ inline operator fun TextSource.plus(text: String) = listOf(this, regular(text))
|
||||
inline operator fun List<TextSource>.plus(text: String) = this + regular(text)
|
||||
|
||||
interface MultilevelTextSource : TextSource {
|
||||
@Deprecated("Will be removed in near major release")
|
||||
val textParts: List<TextPart>
|
||||
get() = textParts(0)
|
||||
val textSources: List<TextSource>
|
||||
val subsources: List<TextSource>
|
||||
}
|
||||
|
||||
data class TextPart(
|
||||
@@ -46,7 +39,7 @@ data class TextPart(
|
||||
|
||||
fun List<TextPart>.justTextSources() = map { it.source }
|
||||
fun List<TextSource>.makeString() = joinToString("") { it.source }
|
||||
internal fun MultilevelTextSource.textParts(offset: Int): List<TextPart> = textSources.toTextParts(offset)
|
||||
internal fun MultilevelTextSource.textParts(offset: Int): List<TextPart> = subsources.toTextParts(offset)
|
||||
fun List<TextSource>.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List<List<TextSource>> {
|
||||
if (isEmpty()) {
|
||||
return emptyList()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.inmo.tgbotapi.CommonAbstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
|
||||
|
||||
interface Texted {
|
||||
val text: String?
|
||||
@@ -19,22 +18,18 @@ interface TextedOutput : ParsableOutput, EntitiesOutput
|
||||
|
||||
interface TextedInput : Texted {
|
||||
/**
|
||||
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
* @see [CaptionedInput.fullEntitiesList]
|
||||
* Here must be full list of entities. This list must contains [TextPart]s with
|
||||
* [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] in case if source text contains parts of
|
||||
* regular text
|
||||
*/
|
||||
val textEntities: List<TextPart>
|
||||
}
|
||||
|
||||
/**
|
||||
* Full list of [TextSource] built from source[TextedInput.textEntities]
|
||||
*
|
||||
* @see TextedInput.textEntities
|
||||
* @see justTextSources
|
||||
*/
|
||||
val TextedInput.textSources
|
||||
get() = textEntities.justTextSources()
|
||||
|
||||
/**
|
||||
* Convert its [TextedInput.textEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
|
||||
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
*/
|
||||
@Deprecated("Currently list of entities already full. This method is redundant")
|
||||
fun TextedInput.fullEntitiesList(): TextSourcesList = text ?.fullListOfSubSource(textEntities) ?.map { it.source } ?: emptyList()
|
||||
|
||||
@@ -3,8 +3,9 @@ package dev.inmo.tgbotapi.bot.Ktor
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.Ktor.base.*
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.EmptyLimiter
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.Response
|
||||
@@ -14,12 +15,39 @@ import io.ktor.client.features.*
|
||||
import io.ktor.client.statement.readText
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class KtorRequestsExecutorBuilder(
|
||||
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
||||
) {
|
||||
var client: HttpClient = HttpClient()
|
||||
var callsFactories: List<KtorCallFactory> = emptyList()
|
||||
var excludeDefaultFactories: Boolean = false
|
||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
||||
var jsonFormatter: Json = nonstrictJsonFormat
|
||||
|
||||
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
||||
}
|
||||
|
||||
inline fun telegramBot(
|
||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
|
||||
|
||||
/**
|
||||
* Shortcut for [telegramBot]
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun telegramBot(
|
||||
token: String,
|
||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
||||
|
||||
class KtorRequestsExecutor(
|
||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||
client: HttpClient = HttpClient(),
|
||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||
excludeDefaultFactories: Boolean = false,
|
||||
private val requestsLimiter: RequestLimiter = EmptyLimiter,
|
||||
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
|
||||
private val jsonFormatter: Json = nonstrictJsonFormat
|
||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
||||
@@ -40,7 +68,7 @@ class KtorRequestsExecutor(
|
||||
return safely(
|
||||
{ e ->
|
||||
throw if (e is ClientRequestException) {
|
||||
val content = e.response ?.readText() ?: throw e
|
||||
val content = e.response.readText()
|
||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||
newRequestException(
|
||||
responseObject,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||
import dev.inmo.tgbotapi.requests.GetUpdates
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.Response
|
||||
import dev.inmo.tgbotapi.types.RetryAfterError
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.receive
|
||||
@@ -13,7 +13,6 @@ import io.ktor.client.features.timeout
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.http.ContentType
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlin.collections.set
|
||||
|
||||
@@ -51,23 +50,17 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||
val content = response.receive<String>()
|
||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||
|
||||
return (responseObject.result?.let {
|
||||
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
|
||||
} ?: responseObject.parameters?.let {
|
||||
val error = it.error
|
||||
if (error is RetryAfterError) {
|
||||
delay(error.leftToRetry)
|
||||
makeCall(client, urlsKeeper, request, jsonFormatter)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} ?: response.let {
|
||||
throw newRequestException(
|
||||
responseObject,
|
||||
content,
|
||||
"Can't get result object from $content"
|
||||
)
|
||||
})
|
||||
return safely {
|
||||
(responseObject.result?.let {
|
||||
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
|
||||
} ?: response.let {
|
||||
throw newRequestException(
|
||||
responseObject,
|
||||
content,
|
||||
"Can't get result object from $content"
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,9 @@ object MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
||||
Headers.build {
|
||||
append(HttpHeaders.ContentType, value.mimeType)
|
||||
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
||||
}
|
||||
) {
|
||||
value.file.asInput()
|
||||
}
|
||||
},
|
||||
block = value.file::input
|
||||
)
|
||||
is FileId -> append(key, value.fileId)
|
||||
else -> append(key, value.toString())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package dev.inmo.tgbotapi.bot.exceptions
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import dev.inmo.tgbotapi.types.Response
|
||||
import dev.inmo.tgbotapi.types.RetryAfterError
|
||||
import io.ktor.utils.io.errors.IOException
|
||||
|
||||
fun newRequestException(
|
||||
@@ -16,6 +18,13 @@ fun newRequestException(
|
||||
description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause)
|
||||
description.contains("PHOTO_INVALID_DIMENSIONS") -> InvalidPhotoDimensionsException(response, plainAnswer, message, cause)
|
||||
description.contains("wrong file identifier") -> WrongFileIdentifierException(response, plainAnswer, message, cause)
|
||||
description.contains("Too Many Requests") -> TooMuchRequestsException(
|
||||
(response.parameters ?.error as? RetryAfterError) ?: RetryAfterError(60, DateTime.now().unixMillisLong),
|
||||
response,
|
||||
plainAnswer,
|
||||
message,
|
||||
cause
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
||||
@@ -49,3 +58,6 @@ class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, m
|
||||
|
||||
class WrongFileIdentifierException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
||||
RequestException(response, plainAnswer, message, cause)
|
||||
|
||||
class TooMuchRequestsException(val retryAfter: RetryAfterError, response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
||||
RequestException(response, plainAnswer, message, cause)
|
||||
|
||||
@@ -1,67 +1,39 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import dev.inmo.tgbotapi.types.MilliSeconds
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
private fun now(): Long = DateTime.nowUnixLong()
|
||||
|
||||
@Serializable
|
||||
class CommonLimiter(
|
||||
private val lockCount: Int = 10,
|
||||
private val regenTime: Long = 20 * 1000L // 20 seconds for full regen of opportunity to send message
|
||||
private val regenTime: MilliSeconds = 15 * 1000, // 15 seconds for full regen of opportunity to send message
|
||||
@Transient
|
||||
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||
) : RequestLimiter {
|
||||
private var doLimit: Boolean = false
|
||||
|
||||
private val counterChannel = Channel<Unit>(Channel.UNLIMITED)
|
||||
private val scope = CoroutineScope(Dispatchers.Default)
|
||||
private val counterJob = scope.launch {
|
||||
var wasLastSecond = 0
|
||||
var lastCountTime = now()
|
||||
var limitManagementJob: Job? = null
|
||||
var removeLimitTime: Long = lastCountTime
|
||||
for (counter in counterChannel) {
|
||||
val now = now()
|
||||
if (now - lastCountTime > 1000) {
|
||||
lastCountTime = now
|
||||
wasLastSecond = 1
|
||||
} else {
|
||||
wasLastSecond++
|
||||
}
|
||||
if (wasLastSecond >= lockCount) {
|
||||
removeLimitTime = now + regenTime
|
||||
if (limitManagementJob == null) {
|
||||
limitManagementJob = launch {
|
||||
doLimit = true
|
||||
var internalNow = now()
|
||||
while (internalNow < removeLimitTime) {
|
||||
delay(removeLimitTime - internalNow)
|
||||
internalNow = now()
|
||||
}
|
||||
doLimit = false
|
||||
}
|
||||
private val quotaSemaphore = Semaphore(lockCount)
|
||||
private val counterRegeneratorJob = scope.launch {
|
||||
val regenDelay: MilliSeconds = (regenTime.toDouble() / lockCount).roundToLong()
|
||||
while (isActive) {
|
||||
delay(regenDelay)
|
||||
if (quotaSemaphore.availablePermits < lockCount) {
|
||||
try {
|
||||
quotaSemaphore.release()
|
||||
} catch (_: IllegalStateException) {
|
||||
// Skip IllegalStateException due to the fact that this exception may happens in release method
|
||||
}
|
||||
}
|
||||
if (now > removeLimitTime) {
|
||||
limitManagementJob = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val quoterChannel = Channel<Unit>(Channel.CONFLATED)
|
||||
private val tickerJob = scope.launch {
|
||||
while (isActive) {
|
||||
quoterChannel.send(Unit)
|
||||
delay(1000L)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun <T> limit(block: suspend () -> T): T {
|
||||
counterChannel.send(Unit)
|
||||
return if (!doLimit) {
|
||||
block()
|
||||
} else {
|
||||
quoterChannel.receive()
|
||||
block()
|
||||
}
|
||||
quotaSemaphore.acquire()
|
||||
return block()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
object EmptyLimiter : RequestLimiter {
|
||||
override suspend fun <T> limit(block: suspend () -> T): T = block()
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.bot.exceptions.TooMuchRequestsException
|
||||
import dev.inmo.tgbotapi.types.MilliSeconds
|
||||
import dev.inmo.tgbotapi.types.RetryAfterError
|
||||
import io.ktor.client.features.ClientRequestException
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
||||
/**
|
||||
* This limiter will limit requests only after getting a [RetryAfterError] or [ClientRequestException] with
|
||||
* [HttpStatusCode.TooManyRequests] status code. Important thing is that in case if some of block has been blocked, all
|
||||
* the others will wait until it will be possible to be called
|
||||
*
|
||||
* @param defaultTooManyRequestsDelay This parameter will be used in case of getting [ClientRequestException] with
|
||||
* [HttpStatusCode.TooManyRequests] as a parameter for delay like it would be [TooMuchRequestsException]. The reason of
|
||||
* it is that in [ClientRequestException] there is no information about required delay between requests
|
||||
*/
|
||||
class ExceptionsOnlyLimiter(
|
||||
private val defaultTooManyRequestsDelay: MilliSeconds = 1000L
|
||||
) : RequestLimiter {
|
||||
private val lockState = MutableStateFlow(false)
|
||||
private suspend fun lock(timeMillis: MilliSeconds) {
|
||||
try {
|
||||
safely {
|
||||
lockState.emit(true)
|
||||
delay(timeMillis)
|
||||
}
|
||||
} finally {
|
||||
lockState.emit(false)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun <T> limit(block: suspend () -> T): T {
|
||||
while (true) {
|
||||
lockState.first { !it }
|
||||
val result = safely({
|
||||
when (it) {
|
||||
is TooMuchRequestsException -> {
|
||||
lock(it.retryAfter.leftToRetry)
|
||||
Result.failure(it)
|
||||
}
|
||||
is ClientRequestException -> {
|
||||
if (it.response.status == HttpStatusCode.TooManyRequests) {
|
||||
lock(defaultTooManyRequestsDelay)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
Result.failure(it)
|
||||
}
|
||||
else -> throw it
|
||||
}
|
||||
}) {
|
||||
Result.success(block())
|
||||
}
|
||||
if (result.isSuccess) {
|
||||
return result.getOrNull()!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.actor
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.types.MilliSeconds
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import kotlin.coroutines.*
|
||||
@@ -9,62 +11,60 @@ import kotlin.math.pow
|
||||
|
||||
private sealed class RequestEvent
|
||||
private class AddRequest(
|
||||
val continuation: Continuation<Long>
|
||||
val continuation: Continuation<MilliSeconds>
|
||||
) : RequestEvent()
|
||||
private object CompleteRequest : RequestEvent()
|
||||
|
||||
@Serializable
|
||||
data class PowLimiter(
|
||||
private val minAwaitTime: Long = 0L,
|
||||
private val maxAwaitTime: Long = 10000L,
|
||||
private val minAwaitTime: MilliSeconds = 0L,
|
||||
private val maxAwaitTime: MilliSeconds = 10000L,
|
||||
private val powValue: Double = 4.0,
|
||||
private val powK: Double = 0.0016
|
||||
private val powK: Double = 1.6,
|
||||
@Transient
|
||||
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||
) : RequestLimiter {
|
||||
@Transient
|
||||
private val scope = CoroutineScope(Dispatchers.Default)
|
||||
@Transient
|
||||
private val eventsChannel = Channel<RequestEvent>(Channel.UNLIMITED)
|
||||
@Transient
|
||||
private val awaitTimeRange = minAwaitTime .. maxAwaitTime
|
||||
@Transient
|
||||
private val eventsChannel = let {
|
||||
var requestsInWork = 0.0
|
||||
scope.actor<RequestEvent> {
|
||||
when (it) {
|
||||
is AddRequest -> {
|
||||
val awaitTime = (requestsInWork.pow(powValue) * powK).toLong()
|
||||
requestsInWork++
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
var requestsInWork: Double = 0.0
|
||||
for (event in eventsChannel) {
|
||||
when (event) {
|
||||
is AddRequest -> {
|
||||
val awaitTime = (((requestsInWork.pow(powValue) * powK) * 1000L).toLong())
|
||||
requestsInWork++
|
||||
|
||||
event.continuation.resume(
|
||||
if (awaitTime in awaitTimeRange) {
|
||||
awaitTime
|
||||
} else {
|
||||
if (awaitTime < minAwaitTime) {
|
||||
minAwaitTime
|
||||
} else {
|
||||
maxAwaitTime
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
is CompleteRequest -> requestsInWork--
|
||||
it.continuation.resume(
|
||||
when {
|
||||
awaitTime in awaitTimeRange -> awaitTime
|
||||
awaitTime < awaitTimeRange.first -> awaitTimeRange.first
|
||||
else -> awaitTimeRange.last
|
||||
}
|
||||
)
|
||||
}
|
||||
is CompleteRequest -> requestsInWork--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun <T> limit(
|
||||
block: suspend () -> T
|
||||
private suspend inline fun <T> withDelay(
|
||||
crossinline block: suspend () -> T
|
||||
): T {
|
||||
val delayMillis = suspendCoroutine<Long> {
|
||||
scope.launch { eventsChannel.send(AddRequest(it)) }
|
||||
}
|
||||
delay(delayMillis)
|
||||
return try {
|
||||
block()
|
||||
safely { block() }
|
||||
} finally {
|
||||
eventsChannel.send(CompleteRequest)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun <T> limit(
|
||||
block: suspend () -> T
|
||||
): T {
|
||||
return withDelay(block)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMember
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMemberSerializerWithoutDeserialization
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMemberSerializer
|
||||
import dev.inmo.tgbotapi.types.chatIdField
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
|
||||
private val chatMembersListSerializer = ListSerializer(
|
||||
AdministratorChatMemberSerializerWithoutDeserialization
|
||||
AdministratorChatMemberSerializer
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.requests.chat.members
|
||||
import dev.inmo.tgbotapi.requests.chat.abstracts.ChatMemberRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMemberDeserializationStrategy
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMemberSerializer
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
@@ -15,7 +15,7 @@ data class GetChatMember(
|
||||
) : ChatMemberRequest<ChatMember> {
|
||||
override fun method(): String = "getChatMember"
|
||||
override val resultDeserializer: DeserializationStrategy<ChatMember>
|
||||
get() = ChatMemberDeserializationStrategy
|
||||
get() = ChatMemberSerializer
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ package dev.inmo.tgbotapi.requests.chat.modify
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||
import dev.inmo.tgbotapi.types.chatIdField
|
||||
import dev.inmo.tgbotapi.types.messageIdField
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ import dev.inmo.tgbotapi.types.MessageEntity.*
|
||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||
import kotlinx.serialization.*
|
||||
|
||||
fun CopyMessage(
|
||||
|
||||
@@ -87,7 +87,7 @@ fun Poll.createRequest(
|
||||
correctOptionId,
|
||||
isAnonymous,
|
||||
isClosed,
|
||||
fullEntitiesList(),
|
||||
textSources,
|
||||
scheduledCloseInfo,
|
||||
disableNotification,
|
||||
replyToMessageId,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.webhook
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||
import dev.inmo.tgbotapi.requests.send.media.base.DataRequest
|
||||
import dev.inmo.tgbotapi.requests.send.media.base.MultipartRequestImpl
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMember
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
data class AdministratorChatMemberImpl(
|
||||
@SerialName(userField)
|
||||
override val user: User,
|
||||
override val canBeEdited: Boolean,
|
||||
override val canChangeInfo: Boolean,
|
||||
override val canPostMessages: Boolean,
|
||||
override val canEditMessages: Boolean,
|
||||
override val canRemoveMessages: Boolean,
|
||||
override val canInviteUsers: Boolean,
|
||||
override val canRestrictMembers: Boolean,
|
||||
override val canPinMessages: Boolean,
|
||||
override val canPromoteMembers: Boolean,
|
||||
override val isAnonymous: Boolean,
|
||||
override val customTitle: String?
|
||||
) : AdministratorChatMember
|
||||
@SerialName(canBeEditedField)
|
||||
override val canBeEdited: Boolean = false,
|
||||
@SerialName(canChangeInfoField)
|
||||
override val canChangeInfo: Boolean = false,
|
||||
@SerialName(canPostMessagesField)
|
||||
override val canPostMessages: Boolean = false,
|
||||
@SerialName(canEditMessagesField)
|
||||
override val canEditMessages: Boolean = false,
|
||||
@SerialName(canDeleteMessagesField)
|
||||
override val canRemoveMessages: Boolean = false,
|
||||
@SerialName(canInviteUsersField)
|
||||
override val canInviteUsers: Boolean = false,
|
||||
@SerialName(canRestrictMembersField)
|
||||
override val canRestrictMembers: Boolean = false,
|
||||
@SerialName(canPinMessagesField)
|
||||
override val canPinMessages: Boolean = false,
|
||||
@SerialName(canPromoteMembersField)
|
||||
override val canPromoteMembers: Boolean = false,
|
||||
@SerialName(isAnonymousField)
|
||||
override val isAnonymous: Boolean = false,
|
||||
@SerialName(customTitleField)
|
||||
override val customTitle: String? = null
|
||||
) : AdministratorChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "administrator"
|
||||
}
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMember
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
data class CreatorChatMember(
|
||||
override val user: User,
|
||||
override val isAnonymous: Boolean,
|
||||
override val customTitle: String?
|
||||
@SerialName(isAnonymousField)
|
||||
override val isAnonymous: Boolean = false,
|
||||
@SerialName(customTitleField)
|
||||
override val customTitle: String? = null
|
||||
) : AdministratorChatMember {
|
||||
@Transient
|
||||
override val canBeEdited: Boolean = true
|
||||
@Transient
|
||||
override val canChangeInfo: Boolean = true
|
||||
@Transient
|
||||
override val canPostMessages: Boolean = true
|
||||
@Transient
|
||||
override val canEditMessages: Boolean = true
|
||||
@Transient
|
||||
override val canRemoveMessages: Boolean = true
|
||||
@Transient
|
||||
override val canInviteUsers: Boolean = true
|
||||
@Transient
|
||||
override val canRestrictMembers: Boolean = true
|
||||
@Transient
|
||||
override val canPinMessages: Boolean = true
|
||||
@Transient
|
||||
override val canPromoteMembers: Boolean = true
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "creator"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.BannedChatMember
|
||||
import dev.inmo.tgbotapi.types.TelegramDate
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
data class KickedChatMember(
|
||||
@SerialName(userField)
|
||||
override val user: User,
|
||||
override val untilDate: TelegramDate?
|
||||
) : BannedChatMember
|
||||
@SerialName(untilDateField)
|
||||
override val untilDate: TelegramDate? = null
|
||||
) : BannedChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "kicked"
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
data class LeftChatMember(override val user: User) :
|
||||
ChatMember
|
||||
@Serializable
|
||||
data class LeftChatMember(@SerialName(userField) override val user: User) : ChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "left"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
data class MemberChatMember(override val user: User) :
|
||||
ChatMember
|
||||
@Serializable
|
||||
data class MemberChatMember(@SerialName(userField) override val user: User) : ChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "member"
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal data class RawChatMember(
|
||||
val user: User,
|
||||
private val status: String,
|
||||
private val until_date: TelegramDate? = null,
|
||||
@SerialName(canBeEditedField)
|
||||
private val canBeEdited: Boolean = false,
|
||||
@SerialName(canChangeInfoField)
|
||||
private val canChangeInfo: Boolean = false,
|
||||
@SerialName(canPostMessagesField)
|
||||
private val canPostMessages: Boolean = false,
|
||||
@SerialName(canEditMessagesField)
|
||||
private val canEditMessages: Boolean = false,
|
||||
@SerialName(canDeleteMessagesField)
|
||||
private val canDeleteMessages: Boolean = false,
|
||||
@SerialName(canInviteUsersField)
|
||||
private val canInviteUsers: Boolean = false,
|
||||
@SerialName(canRestrictMembersField)
|
||||
private val canRestrictMembers: Boolean = false,
|
||||
@SerialName(canPinMessagesField)
|
||||
private val canPinMessages: Boolean = false,
|
||||
@SerialName(canPromoteMembersField)
|
||||
private val canPromoteMembers: Boolean = false,
|
||||
@SerialName(isMemberField)
|
||||
private val isMember: Boolean = false,
|
||||
@SerialName(canSendMessagesField)
|
||||
private val canSendMessages: Boolean = false,
|
||||
@SerialName(canSendMediaMessagesField)
|
||||
private val canSendMediaMessages: Boolean = false,
|
||||
@SerialName(canSendPollsField)
|
||||
private val canSendPolls: Boolean = false,
|
||||
@SerialName(canSendOtherMessagesField)
|
||||
private val canSendOtherMessages: Boolean = false,
|
||||
@SerialName(canAddWebPagePreviewsField)
|
||||
private val canAddWebPagePreviews: Boolean = false,
|
||||
@SerialName(isAnonymousField)
|
||||
private val isAnonymous: Boolean = false,
|
||||
@SerialName(customTitleField)
|
||||
private val customTitle: String? = null
|
||||
) {
|
||||
val asChatMember: ChatMember by lazy {
|
||||
when (status) {
|
||||
"creator" -> CreatorChatMember(user, isAnonymous, customTitle)
|
||||
"administrator" -> AdministratorChatMemberImpl(
|
||||
user,
|
||||
canBeEdited,
|
||||
canChangeInfo,
|
||||
canPostMessages,
|
||||
canEditMessages,
|
||||
canDeleteMessages,
|
||||
canInviteUsers,
|
||||
canRestrictMembers,
|
||||
canPinMessages,
|
||||
canPromoteMembers,
|
||||
isAnonymous,
|
||||
customTitle
|
||||
)
|
||||
"member" -> MemberChatMember(user)
|
||||
"restricted" -> RestrictedChatMember(
|
||||
user,
|
||||
until_date,
|
||||
isMember,
|
||||
canSendMessages,
|
||||
canSendMediaMessages,
|
||||
canSendPolls,
|
||||
canSendOtherMessages,
|
||||
canAddWebPagePreviews,
|
||||
canChangeInfo,
|
||||
canInviteUsers,
|
||||
canPinMessages
|
||||
)
|
||||
"left" -> LeftChatMember(user)
|
||||
"kicked" -> KickedChatMember(
|
||||
user,
|
||||
until_date
|
||||
)
|
||||
else -> throw IllegalStateException("Can't understand type of user: $status")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,36 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.BannedChatMember
|
||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.SpecialRightsChatMember
|
||||
import dev.inmo.tgbotapi.types.TelegramDate
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
data class RestrictedChatMember(
|
||||
@SerialName(userField)
|
||||
override val user: User,
|
||||
override val untilDate: TelegramDate?,
|
||||
val isMember: Boolean,
|
||||
val canSendMessages: Boolean,
|
||||
val canSendMediaMessages: Boolean,
|
||||
val canSendPolls: Boolean,
|
||||
val canSendOtherMessages: Boolean,
|
||||
val canAddWebpagePreviews: Boolean,
|
||||
override val canChangeInfo: Boolean,
|
||||
override val canInviteUsers: Boolean,
|
||||
override val canPinMessages: Boolean
|
||||
) : BannedChatMember, SpecialRightsChatMember
|
||||
@SerialName(untilDateField)
|
||||
override val untilDate: TelegramDate? = null,
|
||||
@SerialName(isMemberField)
|
||||
val isMember: Boolean = false,
|
||||
@SerialName(canSendMessagesField)
|
||||
val canSendMessages: Boolean = false,
|
||||
@SerialName(canSendMediaMessagesField)
|
||||
val canSendMediaMessages: Boolean = false,
|
||||
@SerialName(canSendPollsField)
|
||||
val canSendPolls: Boolean = false,
|
||||
@SerialName(canSendOtherMessagesField)
|
||||
val canSendOtherMessages: Boolean = false,
|
||||
@SerialName(canAddWebPagePreviewsField)
|
||||
val canAddWebpagePreviews: Boolean = false,
|
||||
@SerialName(canChangeInfoField)
|
||||
override val canChangeInfo: Boolean = false,
|
||||
@SerialName(canInviteUsersField)
|
||||
override val canInviteUsers: Boolean = false,
|
||||
@SerialName(canPinMessagesField)
|
||||
override val canPinMessages: Boolean = false
|
||||
) : BannedChatMember, SpecialRightsChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
private val type: String = "restricted"
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember.abstracts
|
||||
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
@Serializable(AdministratorChatMemberSerializer::class)
|
||||
interface AdministratorChatMember : SpecialRightsChatMember {
|
||||
val canBeEdited: Boolean
|
||||
val canPostMessages: Boolean
|
||||
@@ -9,4 +15,12 @@ interface AdministratorChatMember : SpecialRightsChatMember {
|
||||
val canPromoteMembers: Boolean
|
||||
val isAnonymous: Boolean
|
||||
val customTitle: String?
|
||||
}
|
||||
}
|
||||
|
||||
@Serializer(AdministratorChatMember::class)
|
||||
internal object AdministratorChatMemberSerializer : KSerializer<AdministratorChatMember> {
|
||||
override val descriptor: SerialDescriptor = ChatMemberSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): AdministratorChatMember = ChatMemberSerializer.deserialize(decoder) as AdministratorChatMember
|
||||
override fun serialize(encoder: Encoder, value: AdministratorChatMember) = ChatMemberSerializer.serialize(encoder, value)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.types.UntilDate
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(ChatMemberSerializer::class)
|
||||
interface BannedChatMember : ChatMember, UntilDate
|
||||
@@ -1,27 +1,46 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.ChatMember.RawChatMember
|
||||
import dev.inmo.tgbotapi.types.ChatMember.*
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.KSerializer
|
||||
import dev.inmo.tgbotapi.types.statusField
|
||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
@Serializable(ChatMemberSerializer::class)
|
||||
interface ChatMember {
|
||||
val user: User
|
||||
}
|
||||
|
||||
internal object AdministratorChatMemberSerializerWithoutDeserialization : KSerializer<AdministratorChatMember> {
|
||||
override val descriptor: SerialDescriptor = ChatMemberDeserializationStrategy.descriptor
|
||||
@Serializer(ChatMember::class)
|
||||
internal object ChatMemberSerializer : KSerializer<ChatMember> {
|
||||
override val descriptor: SerialDescriptor = JsonObject.serializer().descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): AdministratorChatMember
|
||||
= ChatMemberDeserializationStrategy.deserialize(decoder) as AdministratorChatMember
|
||||
override fun serialize(encoder: Encoder, value: AdministratorChatMember) = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
internal object ChatMemberDeserializationStrategy : DeserializationStrategy<ChatMember> {
|
||||
override val descriptor: SerialDescriptor = RawChatMember.serializer().descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): ChatMember = RawChatMember.serializer().deserialize(decoder).asChatMember
|
||||
override fun deserialize(decoder: Decoder): ChatMember {
|
||||
val json = JsonObject.serializer().deserialize(decoder)
|
||||
return when (json[statusField] ?.jsonPrimitive ?.content ?: error("Status field of chat member must be specified, but incoming json contains next: $json")) {
|
||||
"creator" -> nonstrictJsonFormat.decodeFromJsonElement(CreatorChatMember.serializer(), json)
|
||||
"administrator" -> nonstrictJsonFormat.decodeFromJsonElement(AdministratorChatMemberImpl.serializer(), json)
|
||||
"member" -> nonstrictJsonFormat.decodeFromJsonElement(MemberChatMember.serializer(), json)
|
||||
"restricted" -> nonstrictJsonFormat.decodeFromJsonElement(RestrictedChatMember.serializer(), json)
|
||||
"left" -> nonstrictJsonFormat.decodeFromJsonElement(LeftChatMember.serializer(), json)
|
||||
"kicked" -> nonstrictJsonFormat.decodeFromJsonElement(KickedChatMember.serializer(), json)
|
||||
else -> error("Unknown type of chat member in json: $json")
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: ChatMember) {
|
||||
when (value) {
|
||||
is CreatorChatMember -> CreatorChatMember.serializer()
|
||||
is AdministratorChatMemberImpl -> AdministratorChatMemberImpl.serializer()
|
||||
is MemberChatMember -> MemberChatMember.serializer()
|
||||
is RestrictedChatMember -> RestrictedChatMember.serializer()
|
||||
is LeftChatMember -> LeftChatMember.serializer()
|
||||
is KickedChatMember -> KickedChatMember.serializer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package dev.inmo.tgbotapi.types.ChatMember.abstracts
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(ChatMemberSerializer::class)
|
||||
interface SpecialRightsChatMember : ChatMember {
|
||||
val canChangeInfo: Boolean
|
||||
val canInviteUsers: Boolean
|
||||
|
||||
@@ -28,6 +28,7 @@ typealias GooglePlaceId = String
|
||||
typealias GooglePlaceType = String
|
||||
|
||||
typealias Seconds = Int
|
||||
typealias MilliSeconds = Long
|
||||
typealias LongSeconds = Long
|
||||
|
||||
typealias Meters = Float
|
||||
@@ -60,10 +61,7 @@ val inlineQueryAnswerResultsLimit = 0 .. 50
|
||||
|
||||
val customTitleLength = 0 .. 16
|
||||
|
||||
val dartsAndCubeDiceResultLimit = 1 .. 6
|
||||
@Deprecated("Renamed", ReplaceWith("dartsAndCubeDiceResultLimit", "dev.inmo.tgbotapi.types.dartsAndCubeDiceResultLimit"))
|
||||
val diceResultLimit
|
||||
get() = dartsAndCubeDiceResultLimit
|
||||
val dartsCubeAndBowlingDiceResultLimit = 1 .. 6
|
||||
val basketballAndFootballDiceResultLimit = 1 .. 5
|
||||
val slotMachineDiceResultLimit = 1 .. 64
|
||||
|
||||
@@ -231,6 +229,7 @@ const val canSendPollsField = "can_send_polls"
|
||||
const val canAddWebPagePreviewsField = "can_add_web_page_previews"
|
||||
const val canSetStickerSetField = "can_set_sticker_set"
|
||||
|
||||
const val statusField = "status"
|
||||
const val canBeEditedField = "can_be_edited"
|
||||
const val canChangeInfoField = "can_change_info"
|
||||
const val canPostMessagesField = "can_post_messages"
|
||||
@@ -358,3 +357,13 @@ const val forceField = "force"
|
||||
|
||||
const val regularPollType = "regular"
|
||||
const val quizPollType = "quiz"
|
||||
|
||||
const val dataField = "data"
|
||||
const val credentialsField = "credentials"
|
||||
const val hashField = "hash"
|
||||
const val translationField = "translation"
|
||||
const val filesField = "files"
|
||||
const val frontSideField = "front_side"
|
||||
const val reverseSideField = "reverse_side"
|
||||
const val selfieField = "selfie"
|
||||
const val secretField = "secret"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.audio
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.WithInputMessageContentInlineQueryResult
|
||||
@@ -8,10 +7,5 @@ import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.WithInp
|
||||
const val inlineQueryResultAudioType = "audio"
|
||||
|
||||
interface InlineQueryResultAudioCommon : InlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
WithInputMessageContentInlineQueryResult
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.document
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
|
||||
|
||||
@@ -9,10 +8,5 @@ const val inlineQueryResultDocumentType = "document"
|
||||
interface InlineQueryResultDocumentCommon : InlineQueryResult,
|
||||
TitledInlineQueryResult,
|
||||
DescribedInlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
WithInputMessageContentInlineQueryResult
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.gif
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
|
||||
|
||||
@@ -8,10 +7,5 @@ const val inlineQueryResultGifType = "gif"
|
||||
|
||||
interface InlineQueryResultGifCommon : InlineQueryResult,
|
||||
OptionallyTitledInlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
WithInputMessageContentInlineQueryResult
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.mpeg4gif
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
|
||||
|
||||
@@ -8,10 +7,5 @@ const val inlineQueryResultMpeg4GifType = "mpeg4_gif"
|
||||
|
||||
interface InlineQueryResultMpeg4GifCommon : InlineQueryResult,
|
||||
OptionallyTitledInlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
WithInputMessageContentInlineQueryResult
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.photo
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
|
||||
|
||||
@@ -9,10 +8,5 @@ const val inlineQueryResultPhotoType = "photo"
|
||||
interface InlineQueryResultPhotoCommon : InlineQueryResult,
|
||||
OptionallyTitledInlineQueryResult,
|
||||
DescribedInlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
WithInputMessageContentInlineQueryResult
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.video
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
|
||||
|
||||
@@ -9,10 +8,5 @@ const val inlineQueryResultVideoType = "video"
|
||||
interface InlineQueryResultVideoCommon : InlineQueryResult,
|
||||
TitledInlineQueryResult,
|
||||
DescribedInlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
WithInputMessageContentInlineQueryResult
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
|
||||
|
||||
const val inlineQueryResultVoiceType = "voice"
|
||||
|
||||
interface InlineQueryResultVoiceCommon : InlineQueryResult,
|
||||
CaptionedOutput,
|
||||
TextedOutput,
|
||||
WithInputMessageContentInlineQueryResult,
|
||||
TitledInlineQueryResult {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
}
|
||||
TitledInlineQueryResult
|
||||
|
||||
@@ -37,10 +37,7 @@ data class InputTextMessageContent internal constructor(
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(disableWebPagePreviewField)
|
||||
override val disableWebPagePreview: Boolean? = null
|
||||
) : CaptionedOutput, TextedOutput, DisableWebPagePreview, InputMessageContent {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
) : TextedOutput, DisableWebPagePreview, InputMessageContent {
|
||||
override val entities: List<TextSource>? by lazy {
|
||||
rawEntities ?.asTextParts(text) ?.justTextSources()
|
||||
}
|
||||
|
||||
@@ -3,9 +3,6 @@ package dev.inmo.tgbotapi.types.InputMedia
|
||||
import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Deprecated("Will be removed due to redundancy for end-side users")
|
||||
fun String.toInputMediaFileAttachmentName() = "attach://$this"
|
||||
|
||||
@Serializable(InputMediaSerializer::class)
|
||||
interface InputMedia {
|
||||
val type: String
|
||||
|
||||
@@ -42,16 +42,12 @@ data class InputMediaAnimation internal constructor(
|
||||
override val height: Int? = null,
|
||||
override val duration: Long? = null,
|
||||
override val thumb: InputFile? = null
|
||||
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, TextedOutput, CaptionedOutput {
|
||||
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, TextedOutput {
|
||||
override val type: String = "animation"
|
||||
override val entities: List<TextSource>? by lazy {
|
||||
rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources()
|
||||
}
|
||||
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
|
||||
@SerialName(mediaField)
|
||||
override val media: String
|
||||
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.InputMedia
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.json.Json
|
||||
@@ -16,10 +15,7 @@ internal fun <T> T.buildArguments(withSerializer: SerializationStrategy<T>) = ar
|
||||
)
|
||||
|
||||
@Serializable(MediaGroupMemberInputMediaSerializer::class)
|
||||
interface MediaGroupMemberInputMedia : InputMedia, CaptionedOutput, TextedOutput {
|
||||
@Deprecated("Will be removed in next major release")
|
||||
override val caption: String?
|
||||
get() = text
|
||||
interface MediaGroupMemberInputMedia : InputMedia, TextedOutput {
|
||||
fun serialize(format: StringFormat): String
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.types.InputMedia
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
||||
|
||||
interface ThumbedInputMedia : InputMedia {
|
||||
val thumb: InputFile?
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.boldMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.boldMarkdownV2
|
||||
|
||||
/**
|
||||
* @see bold
|
||||
*/
|
||||
data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.boldMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { boldMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { boldHTML() }
|
||||
override val markdown: String by lazy { source.boldMarkdown() }
|
||||
override val markdownV2: String by lazy { boldMarkdownV2() }
|
||||
override val html: String by lazy { boldHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.commandMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.commandMarkdownV2
|
||||
|
||||
private val commandRegex = Regex("[/!][^@\\s]*")
|
||||
|
||||
@@ -18,9 +17,9 @@ data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstru
|
||||
commandRegex.find(source) ?.value ?.substring(1) ?: source.substring(1)// skip first symbol like "/" or "!"
|
||||
}
|
||||
|
||||
override val asMarkdownSource: String by lazy { source.commandMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { source.commandMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { source.commandHTML() }
|
||||
override val markdown: String by lazy { source.commandMarkdown() }
|
||||
override val markdownV2: String by lazy { source.commandMarkdownV2() }
|
||||
override val html: String by lazy { source.commandHTML() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.cashTagMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.cashTagMarkdownV2
|
||||
|
||||
/**
|
||||
* @see cashTag
|
||||
*/
|
||||
data class CashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.cashTagMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { cashTagMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { cashTagHTML() }
|
||||
override val markdown: String by lazy { source.cashTagMarkdown() }
|
||||
override val markdownV2: String by lazy { cashTagMarkdownV2() }
|
||||
override val html: String by lazy { cashTagHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -2,10 +2,8 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.codeMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.codeMarkdownV2
|
||||
|
||||
/**
|
||||
* @see code
|
||||
@@ -13,9 +11,9 @@ import dev.inmo.tgbotapi.utils.internal.codeMarkdownV2
|
||||
data class CodeTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
override val asMarkdownSource: String by lazy { source.codeMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { source.codeMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { source.codeHTML() }
|
||||
override val markdown: String by lazy { source.codeMarkdown() }
|
||||
override val markdownV2: String by lazy { source.codeMarkdownV2() }
|
||||
override val html: String by lazy { source.codeHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.emailMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.emailMarkdownV2
|
||||
|
||||
/**
|
||||
* @see email
|
||||
*/
|
||||
data class EMailTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.emailMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { emailMarkdownV2(source) }
|
||||
override val asHtmlSource: String by lazy { emailHTML(source) }
|
||||
override val markdown: String by lazy { source.emailMarkdown() }
|
||||
override val markdownV2: String by lazy { emailMarkdownV2(source) }
|
||||
override val html: String by lazy { emailHTML(source) }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.hashTagMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.hashTagMarkdownV2
|
||||
|
||||
/**
|
||||
* @see hashtag
|
||||
*/
|
||||
data class HashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.hashTagMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { hashTagMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { hashTagHTML() }
|
||||
override val markdown: String by lazy { source.hashTagMarkdown() }
|
||||
override val markdownV2: String by lazy { hashTagMarkdownV2() }
|
||||
override val html: String by lazy { hashTagHTML() }
|
||||
|
||||
init {
|
||||
if (!source.startsWith("#")) {
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.italicMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.italicMarkdownV2
|
||||
|
||||
/**
|
||||
* @see italic
|
||||
*/
|
||||
data class ItalicTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.italicMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { italicMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { italicHTML() }
|
||||
override val markdown: String by lazy { source.italicMarkdown() }
|
||||
override val markdownV2: String by lazy { italicMarkdownV2() }
|
||||
override val html: String by lazy { italicHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.mentionMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.mentionMarkdownV2
|
||||
|
||||
private val String.withoutCommercialAt
|
||||
get() = if (startsWith("@")) {
|
||||
@@ -18,11 +16,11 @@ private val String.withoutCommercialAt
|
||||
*/
|
||||
data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.mentionMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { mentionMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { mentionHTML() }
|
||||
override val markdown: String by lazy { source.mentionMarkdown() }
|
||||
override val markdownV2: String by lazy { mentionMarkdownV2() }
|
||||
override val html: String by lazy { mentionHTML() }
|
||||
|
||||
init {
|
||||
if (!source.startsWith("@")) {
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.phoneMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.phoneMarkdownV2
|
||||
|
||||
/**
|
||||
* @see phone
|
||||
*/
|
||||
data class PhoneNumberTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.phoneMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { phoneMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { phoneHTML() }
|
||||
override val markdown: String by lazy { source.phoneMarkdown() }
|
||||
override val markdownV2: String by lazy { phoneMarkdownV2() }
|
||||
override val html: String by lazy { phoneHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.preMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.preMarkdownV2
|
||||
|
||||
/**
|
||||
* @see pre
|
||||
@@ -13,9 +12,9 @@ data class PreTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) c
|
||||
override val source: String,
|
||||
val language: String? = null
|
||||
) : TextSource {
|
||||
override val asMarkdownSource: String by lazy { source.preMarkdown(language) }
|
||||
override val asMarkdownV2Source: String by lazy { source.preMarkdownV2(language) }
|
||||
override val asHtmlSource: String by lazy { source.preHTML(language) }
|
||||
override val markdown: String by lazy { source.preMarkdown(language) }
|
||||
override val markdownV2: String by lazy { source.preMarkdownV2(language) }
|
||||
override val html: String by lazy { source.preHTML(language) }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.regularMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.regularMarkdownV2
|
||||
|
||||
/**
|
||||
* @see regular
|
||||
@@ -12,9 +11,9 @@ import dev.inmo.tgbotapi.utils.internal.regularMarkdownV2
|
||||
data class RegularTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
override val asMarkdownSource: String by lazy { source.regularMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { source.regularMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { source.regularHtml() }
|
||||
override val markdown: String by lazy { source.regularMarkdown() }
|
||||
override val markdownV2: String by lazy { source.regularMarkdownV2() }
|
||||
override val html: String by lazy { source.regularHtml() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.strikethroughMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.strikethroughMarkdownV2
|
||||
|
||||
/**
|
||||
* @see strikethrough
|
||||
*/
|
||||
data class StrikethroughTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asHtmlSource: String by lazy { strikethroughHTML() }
|
||||
override val asMarkdownV2Source: String by lazy { strikethroughMarkdownV2() }
|
||||
override val asMarkdownSource: String by lazy { source.strikethroughMarkdown() }
|
||||
override val html: String by lazy { strikethroughHTML() }
|
||||
override val markdownV2: String by lazy { strikethroughMarkdownV2() }
|
||||
override val markdown: String by lazy { source.strikethroughMarkdown() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.linkMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.linkMarkdownV2
|
||||
|
||||
/**
|
||||
* @see link
|
||||
@@ -13,9 +12,9 @@ data class TextLinkTextSource @RiskFeature(DirectInvocationOfTextSourceConstruct
|
||||
override val source: String,
|
||||
val url: String
|
||||
) : TextSource {
|
||||
override val asMarkdownSource: String by lazy { source.linkMarkdown(url) }
|
||||
override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(url) }
|
||||
override val asHtmlSource: String by lazy { source.linkHTML(url) }
|
||||
override val markdown: String by lazy { source.linkMarkdown(url) }
|
||||
override val markdownV2: String by lazy { source.linkMarkdownV2(url) }
|
||||
override val html: String by lazy { source.linkHTML(url) }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -2,10 +2,8 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.textMentionMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.textMentionMarkdownV2
|
||||
|
||||
/**
|
||||
* @see mention
|
||||
@@ -13,11 +11,11 @@ import dev.inmo.tgbotapi.utils.internal.textMentionMarkdownV2
|
||||
data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
val user: User,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.textMentionMarkdown(user.id) }
|
||||
override val asMarkdownV2Source: String by lazy { textMentionMarkdownV2(user.id) }
|
||||
override val asHtmlSource: String by lazy { textMentionHTML(user.id) }
|
||||
override val markdown: String by lazy { source.textMentionMarkdown(user.id) }
|
||||
override val markdownV2: String by lazy { textMentionMarkdownV2(user.id) }
|
||||
override val html: String by lazy { textMentionHTML(user.id) }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.linkMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.linkMarkdownV2
|
||||
|
||||
/**
|
||||
* @see link
|
||||
@@ -12,9 +11,9 @@ import dev.inmo.tgbotapi.utils.internal.linkMarkdownV2
|
||||
data class URLTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String
|
||||
) : TextSource {
|
||||
override val asMarkdownSource: String by lazy { source.linkMarkdown(source) }
|
||||
override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(source) }
|
||||
override val asHtmlSource: String by lazy { source.linkHTML(source) }
|
||||
override val markdown: String by lazy { source.linkMarkdown(source) }
|
||||
override val markdownV2: String by lazy { source.linkMarkdownV2(source) }
|
||||
override val html: String by lazy { source.linkHTML(source) }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import dev.inmo.tgbotapi.utils.internal.underlineMarkdown
|
||||
import dev.inmo.tgbotapi.utils.internal.underlineMarkdownV2
|
||||
|
||||
/**
|
||||
* @see underline
|
||||
*/
|
||||
data class UnderlineTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val textSources: List<TextSource>
|
||||
override val subsources: List<TextSource>
|
||||
) : MultilevelTextSource {
|
||||
override val asMarkdownSource: String by lazy { source.underlineMarkdown() }
|
||||
override val asMarkdownV2Source: String by lazy { underlineMarkdownV2() }
|
||||
override val asHtmlSource: String by lazy { underlineHTML() }
|
||||
override val markdown: String by lazy { source.underlineMarkdown() }
|
||||
override val markdownV2: String by lazy { underlineMarkdownV2() }
|
||||
override val html: String by lazy { underlineHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.soywiz.klock.DateTime
|
||||
sealed class RequestError
|
||||
|
||||
data class RetryAfterError(
|
||||
val seconds: Long,
|
||||
val seconds: Seconds,
|
||||
val startCountingMillis: Long
|
||||
) : RequestError() {
|
||||
val canContinue = (seconds * 1000L) + startCountingMillis
|
||||
|
||||
@@ -8,7 +8,7 @@ data class ResponseParametersRaw(
|
||||
@SerialName("migrate_to_chat_id")
|
||||
private val migrateToChatId: ChatId? = null,
|
||||
@SerialName("retry_after")
|
||||
private val retryAfter: Long? = null
|
||||
private val retryAfter: Seconds? = null
|
||||
) {
|
||||
@Transient
|
||||
private val createTime: Long = DateTime.now().unixMillisLong
|
||||
|
||||
@@ -14,7 +14,7 @@ sealed class User : PrivateChat
|
||||
|
||||
@Serializable
|
||||
data class CommonUser(
|
||||
override val id: ChatId,
|
||||
override val id: UserId,
|
||||
@SerialName(firstNameField)
|
||||
override val firstName: String,
|
||||
@SerialName(lastNameField)
|
||||
@@ -35,7 +35,7 @@ sealed class Bot : User() {
|
||||
|
||||
@Serializable
|
||||
data class CommonBot(
|
||||
override val id: ChatId,
|
||||
override val id: UserId,
|
||||
@SerialName(usernameField)
|
||||
override val username: Username,
|
||||
@SerialName(firstNameField)
|
||||
@@ -49,7 +49,7 @@ data class CommonBot(
|
||||
|
||||
@Serializable
|
||||
data class ExtendedBot(
|
||||
override val id: ChatId,
|
||||
override val id: UserId,
|
||||
@SerialName(usernameField)
|
||||
override val username: Username,
|
||||
@SerialName(firstNameField)
|
||||
|
||||
@@ -42,6 +42,9 @@ internal object BotActionSerializer: KSerializer<BotAction> {
|
||||
object TypingAction : BotAction() {
|
||||
override val actionName: String = "typing"
|
||||
}
|
||||
inline val typing
|
||||
get() = TypingAction
|
||||
inline fun BotAction.asTyping() = this as? TypingAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is uploading some photo
|
||||
@@ -50,6 +53,9 @@ object TypingAction : BotAction() {
|
||||
object UploadPhotoAction : BotAction() {
|
||||
override val actionName: String = "upload_photo"
|
||||
}
|
||||
inline val uploadPhoto
|
||||
get() = UploadPhotoAction
|
||||
inline fun BotAction.asUploadPhoto() = this as? UploadPhotoAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is recording some video
|
||||
@@ -58,6 +64,9 @@ object UploadPhotoAction : BotAction() {
|
||||
object RecordVideoAction : BotAction() {
|
||||
override val actionName: String = "record_video"
|
||||
}
|
||||
inline val recordVideo
|
||||
get() = RecordVideoAction
|
||||
inline fun BotAction.asRecordVideo() = this as? RecordVideoAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is uploading some photo
|
||||
@@ -66,6 +75,9 @@ object RecordVideoAction : BotAction() {
|
||||
object UploadVideoAction : BotAction() {
|
||||
override val actionName: String = "upload_video"
|
||||
}
|
||||
inline val uploadVideo
|
||||
get() = UploadVideoAction
|
||||
inline fun BotAction.asUploadVideo() = this as? UploadVideoAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is recording some audio
|
||||
@@ -74,6 +86,9 @@ object UploadVideoAction : BotAction() {
|
||||
object RecordAudioAction : BotAction() {
|
||||
override val actionName: String = "record_audio"
|
||||
}
|
||||
inline val recordAudio
|
||||
get() = RecordAudioAction
|
||||
inline fun BotAction.asRecordAudio() = this as? RecordAudioAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is uploading some audio
|
||||
@@ -82,6 +97,9 @@ object RecordAudioAction : BotAction() {
|
||||
object UploadAudioAction : BotAction() {
|
||||
override val actionName: String = "upload_audio"
|
||||
}
|
||||
inline val uploadAudio
|
||||
get() = UploadAudioAction
|
||||
inline fun BotAction.asUploadAudio() = this as? UploadAudioAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is uploading some document
|
||||
@@ -90,6 +108,9 @@ object UploadAudioAction : BotAction() {
|
||||
object UploadDocumentAction : BotAction() {
|
||||
override val actionName: String = "upload_document"
|
||||
}
|
||||
inline val uploadDocument
|
||||
get() = UploadDocumentAction
|
||||
inline fun BotAction.asUploadDocument() = this as? UploadDocumentAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is trying to find location
|
||||
@@ -98,6 +119,9 @@ object UploadDocumentAction : BotAction() {
|
||||
object FindLocationAction : BotAction() {
|
||||
override val actionName: String = "find_location"
|
||||
}
|
||||
inline val findLocation
|
||||
get() = FindLocationAction
|
||||
inline fun BotAction.asFindLocation() = this as? FindLocationAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is recording video note
|
||||
@@ -106,6 +130,9 @@ object FindLocationAction : BotAction() {
|
||||
object RecordVideoNoteAction : BotAction() {
|
||||
override val actionName: String = "record_video_note"
|
||||
}
|
||||
inline val recordVideoNote
|
||||
get() = RecordVideoNoteAction
|
||||
inline fun BotAction.asRecordVideoNote() = this as? RecordVideoNoteAction
|
||||
|
||||
/**
|
||||
* Will notify user that bot is uploading video note
|
||||
@@ -114,3 +141,6 @@ object RecordVideoNoteAction : BotAction() {
|
||||
object UploadVideoNoteAction : BotAction() {
|
||||
override val actionName: String = "upload_video_note"
|
||||
}
|
||||
inline val uploadVideoNote
|
||||
get() = UploadVideoNoteAction
|
||||
inline fun BotAction.asUploadVideoNote() = this as? UploadVideoNoteAction
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package dev.inmo.tgbotapi.types.chat.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.UserId
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChatSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
interface PrivateChat : Chat, UsernameChat {
|
||||
override val id: UserId
|
||||
val firstName: String
|
||||
val lastName: String
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ sealed class DiceAnimationType {
|
||||
object CubeDiceAnimationType : DiceAnimationType() {
|
||||
override val emoji: String = "\uD83C\uDFB2"
|
||||
override val valueLimits: IntRange
|
||||
get() = dartsAndCubeDiceResultLimit
|
||||
get() = dartsCubeAndBowlingDiceResultLimit
|
||||
}
|
||||
@Serializable(DiceAnimationTypeSerializer::class)
|
||||
object DartsDiceAnimationType : DiceAnimationType() {
|
||||
override val emoji: String = "\uD83C\uDFAF"
|
||||
override val valueLimits: IntRange
|
||||
get() = dartsAndCubeDiceResultLimit
|
||||
get() = dartsCubeAndBowlingDiceResultLimit
|
||||
}
|
||||
@Serializable(DiceAnimationTypeSerializer::class)
|
||||
object BasketballDiceAnimationType : DiceAnimationType() {
|
||||
@@ -36,6 +36,12 @@ object FootballDiceAnimationType : DiceAnimationType() {
|
||||
get() = basketballAndFootballDiceResultLimit
|
||||
}
|
||||
@Serializable(DiceAnimationTypeSerializer::class)
|
||||
object BowlingDiceAnimationType : DiceAnimationType() {
|
||||
override val emoji: String = "\uD83C\uDFB3"
|
||||
override val valueLimits: IntRange
|
||||
get() = dartsCubeAndBowlingDiceResultLimit
|
||||
}
|
||||
@Serializable(DiceAnimationTypeSerializer::class)
|
||||
object SlotMachineDiceAnimationType : DiceAnimationType() {
|
||||
override val emoji: String = "\uD83C\uDFB0"
|
||||
override val valueLimits: IntRange
|
||||
@@ -59,6 +65,7 @@ internal object DiceAnimationTypeSerializer : KSerializer<DiceAnimationType> {
|
||||
BasketballDiceAnimationType.emoji -> BasketballDiceAnimationType
|
||||
SlotMachineDiceAnimationType.emoji -> SlotMachineDiceAnimationType
|
||||
FootballDiceAnimationType.emoji -> FootballDiceAnimationType
|
||||
BowlingDiceAnimationType.emoji -> BowlingDiceAnimationType
|
||||
else -> CustomDiceAnimationType(type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.types.FileUniqueId
|
||||
|
||||
internal const val fileIdField = "file_id"
|
||||
internal const val fileSizeField = "file_size"
|
||||
internal const val fileDateField = "file_date"
|
||||
internal const val filePathField = "file_path"
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,9 +6,9 @@ import dev.inmo.tgbotapi.types.chat.abstracts.ChannelChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||
|
||||
data class ChannelEventMessage(
|
||||
data class ChannelEventMessage<T : ChannelEvent>(
|
||||
override val messageId: MessageIdentifier,
|
||||
override val chat: ChannelChat,
|
||||
override val chatEvent: ChannelEvent,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : ChatEventMessage
|
||||
) : ChatEventMessage<T>
|
||||
|
||||
@@ -20,6 +20,3 @@ data class ChannelMessageImpl<T: MessageContent>(
|
||||
override val senderBot: CommonBot?,
|
||||
override val authorSignature: AuthorSignature?
|
||||
) : ChannelMessage<T>
|
||||
|
||||
@Deprecated("Renamed", ReplaceWith("ChannelMessageImpl", "dev.inmo.tgbotapi.types.message.ChannelMessageImpl"))
|
||||
typealias ChannelMessage<T> = ChannelMessageImpl<T>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts
|
||||
|
||||
interface SupergroupEvent: ChatEvent
|
||||
interface SupergroupEvent: GroupEvent
|
||||
@@ -7,13 +7,10 @@ import dev.inmo.tgbotapi.types.chat.abstracts.GroupChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.GroupEventMessage
|
||||
|
||||
@Deprecated("Renamed", ReplaceWith("CommonGroupEventMessage"))
|
||||
typealias GroupEventMessage = CommonGroupEventMessage
|
||||
|
||||
data class CommonGroupEventMessage(
|
||||
data class CommonGroupEventMessage<T : GroupEvent>(
|
||||
override val messageId: MessageIdentifier,
|
||||
override val user: User,
|
||||
override val chat: GroupChat,
|
||||
override val chatEvent: GroupEvent,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : GroupEventMessage
|
||||
) : GroupEventMessage<T>
|
||||
|
||||
@@ -7,13 +7,10 @@ import dev.inmo.tgbotapi.types.chat.abstracts.SupergroupChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
|
||||
|
||||
@Deprecated("Renamed", ReplaceWith("CommonSupergroupEventMessage"))
|
||||
typealias SupergroupEventMessage = CommonSupergroupEventMessage
|
||||
|
||||
data class CommonSupergroupEventMessage(
|
||||
data class CommonSupergroupEventMessage<T : SupergroupEvent>(
|
||||
override val messageId: MessageIdentifier,
|
||||
override val user: User,
|
||||
override val chat: SupergroupChat,
|
||||
override val chatEvent: SupergroupEvent,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : SupergroupEventMessage
|
||||
) : SupergroupEventMessage<T>
|
||||
|
||||
@@ -38,6 +38,7 @@ data class AnonymousGroupMessageImpl<T : MessageContent>(
|
||||
data class CommonGroupMessageImpl<T : MessageContent>(
|
||||
override val chat: GroupChat,
|
||||
override val messageId: MessageIdentifier,
|
||||
override val user: User,
|
||||
override val date: DateTime,
|
||||
override val forwardInfo: ForwardInfo?,
|
||||
override val editDate: DateTime?,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.inmo.tgbotapi.types.message
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||
import dev.inmo.tgbotapi.types.User
|
||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.FromUserMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
import dev.inmo.tgbotapi.types.passport.PassportData
|
||||
|
||||
data class PassportMessage(
|
||||
override val messageId: MessageIdentifier,
|
||||
override val chat: Chat,
|
||||
override val user: User,
|
||||
override val date: DateTime,
|
||||
val passportData: PassportData
|
||||
) : Message, FromUserMessage
|
||||
@@ -22,6 +22,3 @@ data class PrivateMessageImpl<T: MessageContent>(
|
||||
override val senderBot: CommonBot?,
|
||||
val paymentInfo: SuccessfulPaymentInfo?
|
||||
) : PrivateMessage<T>
|
||||
|
||||
@Deprecated("Renamed", ReplaceWith("PrivateMessageImpl", "dev.inmo.tgbotapi.types.message.PrivateMessageImpl"))
|
||||
typealias CommonMessageImpl<T> = PrivateMessageImpl<T>
|
||||
|
||||
@@ -18,6 +18,7 @@ import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentInfo
|
||||
import dev.inmo.tgbotapi.types.passport.PassportData
|
||||
import dev.inmo.tgbotapi.types.payments.Invoice
|
||||
import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
|
||||
import dev.inmo.tgbotapi.types.polls.Poll
|
||||
@@ -84,7 +85,7 @@ internal data class RawMessage(
|
||||
private val connected_website: String? = null,
|
||||
|
||||
// passport property
|
||||
private val passport_data: Unit? = null,
|
||||
private val passport_data: PassportData? = null,
|
||||
private val proximity_alert_triggered: ProximityAlertTriggered? = null,
|
||||
|
||||
private val reply_markup: InlineKeyboardMarkup? = null
|
||||
@@ -296,6 +297,7 @@ internal data class RawMessage(
|
||||
null -> CommonGroupMessageImpl(
|
||||
chat,
|
||||
messageId,
|
||||
from ?: error("It is expected that in messages from non anonymous users and channels user must be specified"),
|
||||
date.asDate,
|
||||
forwarded,
|
||||
edit_date ?.asDate,
|
||||
@@ -323,6 +325,14 @@ internal data class RawMessage(
|
||||
)
|
||||
else -> error("Unknown type of chat: $chat")
|
||||
}
|
||||
} ?: passport_data ?.let{
|
||||
PassportMessage(
|
||||
messageId,
|
||||
chat,
|
||||
from ?: error("For passport must be provided user, but got null"),
|
||||
date.asDate,
|
||||
passport_data
|
||||
)
|
||||
} ?: error("Was not found supported type of data")
|
||||
} catch (e: Exception) {
|
||||
UnknownMessageType(
|
||||
|
||||
@@ -2,6 +2,6 @@ package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent
|
||||
|
||||
interface ChatEventMessage : Message {
|
||||
val chatEvent: ChatEvent
|
||||
interface ChatEventMessage<T : ChatEvent> : Message {
|
||||
val chatEvent: T
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
interface GroupEventMessage : ChatEventMessage, FromUserMessage
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent
|
||||
|
||||
interface GroupEventMessage<T : GroupEvent> : ChatEventMessage<T>, FromUserMessage
|
||||
|
||||
@@ -17,4 +17,4 @@ interface AnonymousGroupMessage<T : MessageContent> : GroupMessage<T>, SignedMes
|
||||
override val senderChat: GroupChat
|
||||
get() = chat
|
||||
}
|
||||
interface CommonGroupMessage<T : MessageContent> : GroupMessage<T>
|
||||
interface CommonGroupMessage<T : MessageContent> : GroupMessage<T>, FromUserMessage
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
interface SupergroupEventMessage : GroupEventMessage
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
|
||||
|
||||
interface SupergroupEventMessage<T : SupergroupEvent> : GroupEventMessage<T>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.content
|
||||
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.requests.send.SendTextMessage
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
@@ -11,17 +11,11 @@ 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.*
|
||||
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
|
||||
import dev.inmo.tgbotapi.utils.internal.toMarkdownTexts
|
||||
|
||||
data class TextContent(
|
||||
val text: String,
|
||||
/**
|
||||
* Not full list of entities. This list WILL NOT contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
* @see [TextContent.fullEntitiesList]
|
||||
*/
|
||||
val entities: List<TextPart> = emptyList()
|
||||
) : MessageContent {
|
||||
override val text: String,
|
||||
override val textEntities: List<TextPart> = emptyList()
|
||||
) : MessageContent, TextedInput {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
disableNotification: Boolean,
|
||||
@@ -78,9 +72,3 @@ data class TextContent(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert its [TextContent.entities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
|
||||
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||
*/
|
||||
fun TextContent.fullEntitiesList(): TextSourcesList = text.fullListOfSubSource(entities).map { it.source }
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.inmo.tgbotapi.types.passport
|
||||
|
||||
import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
typealias EncryptedAndBase64EncodedData = String
|
||||
typealias EncryptedByBotPublicKeyData = String
|
||||
typealias EncryptedData = String
|
||||
|
||||
@Serializable
|
||||
data class EncryptedCredentials(
|
||||
@SerialName(dataField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
val data: EncryptedData,
|
||||
@SerialName(hashField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
val hash: String,
|
||||
@SerialName(secretField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
val secret: EncryptedByBotPublicKeyData
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.inmo.tgbotapi.types.passport
|
||||
|
||||
import dev.inmo.tgbotapi.types.credentialsField
|
||||
import dev.inmo.tgbotapi.types.dataField
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.EncryptedPassportElement
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class PassportData(
|
||||
@SerialName(dataField)
|
||||
val data: List<EncryptedPassportElement>,
|
||||
@SerialName(credentialsField)
|
||||
val credentials: EncryptedCredentials
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer
|
||||
import dev.inmo.tgbotapi.types.emailField
|
||||
import dev.inmo.tgbotapi.types.hashField
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithEmail
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Email(
|
||||
@SerialName(emailField)
|
||||
override val email: String,
|
||||
@SerialName(hashField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val hash: String
|
||||
) : WithEmail {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer
|
||||
import dev.inmo.tgbotapi.types.dataField
|
||||
import dev.inmo.tgbotapi.types.passport.EncryptedData
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithData
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class EncryptedAddress(
|
||||
@SerialName(dataField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val data: EncryptedData,
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val hash: String
|
||||
) : WithData
|
||||
@@ -0,0 +1,87 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.tgbotapi.types.hashField
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.EncryptedPassportElement
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.UnknownEncryptedPassportElement
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
@Serializer(EncryptedPassportElement::class)
|
||||
object EncryptedElementSerializer : KSerializer<EncryptedPassportElement> {
|
||||
private val jsonSerializer = JsonObject.serializer()
|
||||
override val descriptor: SerialDescriptor = jsonSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): EncryptedPassportElement {
|
||||
val json = jsonSerializer.deserialize(decoder)
|
||||
return when (json[typeField] ?.jsonPrimitive ?.content) {
|
||||
"personal_details" -> nonstrictJsonFormat.decodeFromJsonElement(EncryptedPersonalDetails.serializer(), json)
|
||||
"passport" -> nonstrictJsonFormat.decodeFromJsonElement(CommonPassport.serializer(), json)
|
||||
"driver_license" -> nonstrictJsonFormat.decodeFromJsonElement(DriverLicense.serializer(), json)
|
||||
"identity_card" -> nonstrictJsonFormat.decodeFromJsonElement(IdentityCard.serializer(), json)
|
||||
"internal_passport" -> nonstrictJsonFormat.decodeFromJsonElement(InternalPassport.serializer(), json)
|
||||
"address" -> nonstrictJsonFormat.decodeFromJsonElement(EncryptedAddress.serializer(), json)
|
||||
"utility_bill" -> nonstrictJsonFormat.decodeFromJsonElement(UtilityBill.serializer(), json)
|
||||
"bank_statement" -> nonstrictJsonFormat.decodeFromJsonElement(BankStatement.serializer(), json)
|
||||
"rental_agreement" -> nonstrictJsonFormat.decodeFromJsonElement(RentalAgreement.serializer(), json)
|
||||
"passport_registration" -> nonstrictJsonFormat.decodeFromJsonElement(PassportRegistration.serializer(), json)
|
||||
"temporary_registration" -> nonstrictJsonFormat.decodeFromJsonElement(TemporaryRegistration.serializer(), json)
|
||||
"phone_number" -> nonstrictJsonFormat.decodeFromJsonElement(PhoneNumber.serializer(), json)
|
||||
"email" -> nonstrictJsonFormat.decodeFromJsonElement(Email.serializer(), json)
|
||||
else -> UnknownEncryptedPassportElement(json, json[hashField] ?.jsonPrimitive ?.content ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: EncryptedPassportElement) {
|
||||
val json = when (value) {
|
||||
is EncryptedPersonalDetails -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(EncryptedPersonalDetails.serializer(), value).jsonObject + (typeField to JsonPrimitive("personal_details"))
|
||||
)
|
||||
is CommonPassport -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(CommonPassport.serializer(), value).jsonObject + (typeField to JsonPrimitive("passport"))
|
||||
)
|
||||
is DriverLicense -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(DriverLicense.serializer(), value).jsonObject + (typeField to JsonPrimitive("driver_license"))
|
||||
)
|
||||
is IdentityCard -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(IdentityCard.serializer(), value).jsonObject + (typeField to JsonPrimitive("identity_card"))
|
||||
)
|
||||
is InternalPassport -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(InternalPassport.serializer(), value).jsonObject + (typeField to JsonPrimitive("internal_passport"))
|
||||
)
|
||||
is EncryptedAddress -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(EncryptedAddress.serializer(), value).jsonObject + (typeField to JsonPrimitive("address"))
|
||||
)
|
||||
is UtilityBill -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(UtilityBill.serializer(), value).jsonObject + (typeField to JsonPrimitive("utility_bill"))
|
||||
)
|
||||
is BankStatement -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(BankStatement.serializer(), value).jsonObject + (typeField to JsonPrimitive("bank_statement"))
|
||||
)
|
||||
is RentalAgreement -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(RentalAgreement.serializer(), value).jsonObject + (typeField to JsonPrimitive("rental_agreement"))
|
||||
)
|
||||
is PassportRegistration -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(PassportRegistration.serializer(), value).jsonObject + (typeField to JsonPrimitive("passport_registration"))
|
||||
)
|
||||
is TemporaryRegistration -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(TemporaryRegistration.serializer(), value).jsonObject + (typeField to JsonPrimitive("temporary_registration"))
|
||||
)
|
||||
is PhoneNumber -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(PhoneNumber.serializer(), value).jsonObject + (typeField to JsonPrimitive("phone_number"))
|
||||
)
|
||||
is Email -> JsonObject(
|
||||
nonstrictJsonFormat.encodeToJsonElement(Email.serializer(), value).jsonObject + (typeField to JsonPrimitive("email"))
|
||||
)
|
||||
is UnknownEncryptedPassportElement -> value.rawJson
|
||||
else -> return
|
||||
}
|
||||
jsonSerializer.serialize(encoder, json)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer
|
||||
import dev.inmo.tgbotapi.types.dataField
|
||||
import dev.inmo.tgbotapi.types.passport.EncryptedData
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithData
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class EncryptedPersonalDetails(
|
||||
@SerialName(dataField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val data: EncryptedData,
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val hash: String
|
||||
) : WithData
|
||||
@@ -0,0 +1,42 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.passport.EncryptedData
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(EncryptedElementSerializer::class)
|
||||
sealed class Passport : WithData, WithFrontSide, WithSelfie, Translatable
|
||||
|
||||
@Serializable
|
||||
data class CommonPassport(
|
||||
@SerialName(dataField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val data: EncryptedData,
|
||||
@SerialName(frontSideField)
|
||||
override val frontSide: PassportFile? = null,
|
||||
@SerialName(selfieField)
|
||||
override val selfie: PassportFile? = null,
|
||||
@SerialName(translationField)
|
||||
override val translations: List<PassportFile> = emptyList(),
|
||||
@SerialName(hashField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val hash: String
|
||||
) : Passport()
|
||||
@Serializable
|
||||
data class InternalPassport(
|
||||
@SerialName(dataField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val data: EncryptedData,
|
||||
@SerialName(frontSideField)
|
||||
override val frontSide: PassportFile? = null,
|
||||
@SerialName(selfieField)
|
||||
override val selfie: PassportFile? = null,
|
||||
@SerialName(translationField)
|
||||
override val translations: List<PassportFile> = emptyList(),
|
||||
@SerialName(hashField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val hash: String
|
||||
) : Passport()
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* This object represents a file uploaded to Telegram Passport. Currently all Telegram Passport files are in JPEG format
|
||||
* when decrypted and don't exceed 10MB.
|
||||
*/
|
||||
@Serializable
|
||||
data class PassportFile(
|
||||
@SerialName(fileIdField)
|
||||
override val fileId: FileId,
|
||||
@SerialName(fileUniqueIdField)
|
||||
override val fileUniqueId: FileUniqueId,
|
||||
@SerialName(fileDateField)
|
||||
val uploadingDate: TelegramDate,
|
||||
@SerialName(fileSizeField)
|
||||
override val fileSize: Long? = null
|
||||
) : TelegramMediaFile
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.inmo.tgbotapi.types.passport.encrypted_data
|
||||
|
||||
import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer
|
||||
import dev.inmo.tgbotapi.types.hashField
|
||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithPhoneNumber
|
||||
import dev.inmo.tgbotapi.types.phoneNumberField
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class PhoneNumber(
|
||||
@SerialName(phoneNumberField)
|
||||
override val phoneNumber: String,
|
||||
@SerialName(hashField)
|
||||
@Serializable(Base64StringSerializer::class)
|
||||
override val hash: String
|
||||
) : WithPhoneNumber {
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user