mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-18 13:00:18 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb08732938 |
11
.github/dependabot.yml
vendored
11
.github/dependabot.yml
vendored
@@ -1,11 +0,0 @@
|
|||||||
# To get started with Dependabot version updates, you'll need to specify which
|
|
||||||
# package ecosystems to update and where the package manifests are located.
|
|
||||||
# Please see the documentation for all configuration options:
|
|
||||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
||||||
|
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "gradle" # See documentation for possible values
|
|
||||||
directory: "/tgbotapi.core" # Location of package manifests
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -1,12 +0,0 @@
|
|||||||
name: Build
|
|
||||||
on: [push]
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-java@v1
|
|
||||||
with:
|
|
||||||
java-version: 1.8
|
|
||||||
- name: Build
|
|
||||||
run: ./gradlew build
|
|
||||||
21
.github/workflows/kdocs.yml
vendored
21
.github/workflows/kdocs.yml
vendored
@@ -1,21 +0,0 @@
|
|||||||
name: Publish KDocs
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
jobs:
|
|
||||||
publishing:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-java@v1
|
|
||||||
with:
|
|
||||||
java-version: 1.8
|
|
||||||
- name: Build
|
|
||||||
run: ./gradlew dokkaHtml
|
|
||||||
- name: Publish KDocs
|
|
||||||
uses: peaceiris/actions-gh-pages@v3
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
publish_dir: ./docs/build/dokka/html
|
|
||||||
publish_branch: kdocs
|
|
||||||
21
.github/workflows/packages_publishing.yml
vendored
21
.github/workflows/packages_publishing.yml
vendored
@@ -1,21 +0,0 @@
|
|||||||
name: Publish package to GitHub Packages
|
|
||||||
on: [push]
|
|
||||||
jobs:
|
|
||||||
publishing:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-java@v1
|
|
||||||
with:
|
|
||||||
java-version: 1.8
|
|
||||||
- name: Rewrite version
|
|
||||||
run: |
|
|
||||||
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
|
|
||||||
cat gradle.properties | sed -e "s/^library_version=\([0-9\.]*\)/library_version=\1-branch_$branch-build${{ github.run_number }}/" > gradle.properties.tmp
|
|
||||||
rm gradle.properties
|
|
||||||
mv gradle.properties.tmp gradle.properties
|
|
||||||
- name: Publish
|
|
||||||
run: ./gradlew publishAllPublicationsToGithubPackagesRepository --no-parallel -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication
|
|
||||||
env:
|
|
||||||
GITHUBPACKAGES_USER: ${{ github.actor }}
|
|
||||||
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
1
.github/write-good.yml
vendored
Normal file
1
.github/write-good.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
spellchecker: true
|
||||||
708
CHANGELOG.md
708
CHANGELOG.md
@@ -1,713 +1,5 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
## 0.35.3
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Klock`: `2.2.0` -> `2.3.1`
|
|
||||||
* `Ktor`: `1.6.1` -> `1.6.2`
|
|
||||||
* `MicroUtils`: `0.5.16` -> `0.5.18`
|
|
||||||
* `Core`:
|
|
||||||
* **`SimpleRequestCallFactory` and `MultipartRequestCallFactory` became a classes instead of objects to avoid
|
|
||||||
collisions in different bots**
|
|
||||||
* Support of strongly-typed ietf language codes has been added
|
|
||||||
* `API`:
|
|
||||||
* New extension `TelegramBot#downloadFile` for any `MediaContent`
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* New provider `defaultCoroutineScopeProvider`
|
|
||||||
* Now it is not necessary to provide `CoroutineScope` to `TelegramBot#buildBehaviour`
|
|
||||||
extension
|
|
||||||
* New `TelegramBot#buildBehaviour` extension with `FlowUpdatesFilter` and `CoroutineScope` with
|
|
||||||
default `CoroutineScope`
|
|
||||||
* New typealias `SimpleFilter` for unifying triggers filter signatures
|
|
||||||
* All waiters got real filters (`SimpleFilter`) and rename old filters as mappers
|
|
||||||
* New extensions for `Any`: `as`/`when`/`require` for `WithOptionalLanguageCode` and `WithLanguageCode`
|
|
||||||
|
|
||||||
## 0.35.2
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Kotlin`: `1.5.20` -> `1.5.21`
|
|
||||||
* `Coroutines`: `1.5.0` -> `1.5.1`
|
|
||||||
* `Serialization`: `1.2.1` -> `1.2.2`
|
|
||||||
* `Klock`: `2.1.2` -> `2.2.0`
|
|
||||||
* `Ktor`: `1.6.0` -> `1.6.1`
|
|
||||||
* `MicroUtils`: `0.5.15` -> `0.5.16`
|
|
||||||
|
|
||||||
## 0.35.1
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Kotlin`: `1.5.10` -> `1.5.20`
|
|
||||||
* `MicroUtils`: `0.5.6` -> `0.5.15`
|
|
||||||
* `Core`:
|
|
||||||
* New interface `MyCommandsRequest` (also see `Bot API 5.3` below)
|
|
||||||
* New extensions `TextSourcesList#make*String` for all parse modes
|
|
||||||
* All `MessageContent` subclasses now serializable
|
|
||||||
* `ChosenInlineResult` was replaced and modified to be sealed
|
|
||||||
* `ChosenInlineResult` now extends `FromUser`
|
|
||||||
* Added `Update#sourceUser` method
|
|
||||||
* More types assumed as sent by user types now implements `FromUser` interface
|
|
||||||
* Added `Any#whenFromUser`, `Any#asFromUser` and`Any#requireFromUser` extensions
|
|
||||||
* `MedaGroupUpdate` and its direct extenders `SentMediaGroupUpdate` and `EditMediaGroupUpdate` became
|
|
||||||
`sealed interface`s
|
|
||||||
* New built-in `RequestException` implementator `GetUpdatesConflict` has been added
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* ❗️ All triggers (`on*` extensions) have been modified to work in parallel by some marker by default (new parameter
|
|
||||||
`markerFactory`, in most cases will work async for different chats)
|
|
||||||
* New extensions `telegramBotWithBehaviour`
|
|
||||||
* All behaviour builder extensions got new parameter `defaultExceptionsHandler`
|
|
||||||
* Class `BehaviourContext` was rewritten as an interface with default realization `DefaultBehaviourContext` and
|
|
||||||
factory `BehaviourContext(TelegramBot, CoroutineScope, FlowsUpdatesFilter)`
|
|
||||||
* Extension `buildBehaviour` (and all related extensions/functions) for opportunity to pass
|
|
||||||
`defaultExceptionsHandler`
|
|
||||||
* Trigger `onContentMessage` and waiter `waitContentMessage` now may include media groups
|
|
||||||
* `API`:
|
|
||||||
* All `reply` and subsequent extensions have been replaced in send package
|
|
||||||
* `Utils`:
|
|
||||||
* With class casts like `as*` and `require*` now you may use `when*` with parameter callback
|
|
||||||
* Methods of `EntitiesBuilder` now will return builder itself, so you may create sequences like
|
|
||||||
`buildEntities { bold("Hello,") + italic(" world") }` directly in `buildEntities` body
|
|
||||||
* New extension `TelegramBot#longPollingFlow` has been added with returning value `Flow` with updates
|
|
||||||
* `Bot API 5.3`:
|
|
||||||
* Add type `BotCommandScope`, its serializer `BotCommandScopeSerializer` and all its children
|
|
||||||
* New request `DeleteMyCommands` and updates in `GetMyCommands` and `SetMyCommands`
|
|
||||||
* Renames according to `And more` of [June 25, 2021](https://core.telegram.org/bots/api-changelog#june-25-2021) update
|
|
||||||
|
|
||||||
## 0.35.0
|
|
||||||
|
|
||||||
**ALL PREVIOUS DEPRECATIONS HAVE BEEN REMOVED**
|
|
||||||
**JS PART NOW USE IR COMPILER ONLY**
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Kotlin`: `1.4.72` -> `1.5.10`
|
|
||||||
* `MicroUtils`: `0.4.36` -> `0.5.6`
|
|
||||||
* `Coroutines`: `1.4.3` -> `1.5.0`
|
|
||||||
* `Serialization`: `1.1.0` -> `1.2.1`
|
|
||||||
* `Klock`: `2.0.7` -> `2.1.2`
|
|
||||||
* `UUID`: `0.2.3` -> `0.3.0`
|
|
||||||
* `Ktor`: `1.5.4` -> `1.6.0`
|
|
||||||
* `Core`:
|
|
||||||
* `ForceReply` has been renamed to `ReplyForce`
|
|
||||||
* `Captioned` and `Explained` interfaces have been removed
|
|
||||||
* `RecordAudioAction` and `UploadAudioAction` (and all related to these actions functionality) have been removed
|
|
||||||
* `TextSource` interface and all related things have been replaced
|
|
||||||
* `CallbackQuery` interface and all its extenders/implementers become `sealed`
|
|
||||||
* `InputMedia` interface and all its extenders/implementers become `sealed`
|
|
||||||
* `ParseMode` interface and all its extenders/implementers become `sealed`
|
|
||||||
* `ChatMember` becomes `sealed`
|
|
||||||
* `KeyboardMarkup` becomes `sealed`
|
|
||||||
* `LeftChatMember` and `MemberChatMember` become interfaces. All their code were replaced to the `*Impl` classes
|
|
||||||
* Most of `sealed` classes have been modified to be interfaces
|
|
||||||
* Most serializers becomes public, but they are still `RistFeature`
|
|
||||||
* For `EntitiesBuilder` multilevel text sources builders with callback have been added
|
|
||||||
|
|
||||||
## 0.34.1
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `ktor`: `1.5.3` -> `1.5.4`
|
|
||||||
* `MicroUtils`: `0.4.35` -> `0.4.36`
|
|
||||||
* `Core`
|
|
||||||
* Fix in creating of text sources list
|
|
||||||
|
|
||||||
## 0.34.0
|
|
||||||
|
|
||||||
_**It is recommended to use [0.34.1](https://github.com/InsanusMokrassar/TelegramBotAPI/releases/tag/0.34.1) version due to the bug in 0.34.0 related to rewriting of `TextSource`s creating mechanism.**_
|
|
||||||
|
|
||||||
**UPDATE UP TO Telegram Bot API 5.2**
|
|
||||||
|
|
||||||
_**ALL OLD DEPRECATIONS WERE REMOVED**_
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* Type `ChatType` has been added
|
|
||||||
* New `ExtendedChat` for unknown messages `UnknownExtendedChat` has been added
|
|
||||||
* `SendInvoice#startParameter` becomes optional and replaced in `SendInvoice` constructor
|
|
||||||
* New interface `CommonSendInvoiceData` has been added
|
|
||||||
* Fields `CommonSendInvoiceData#maxTipAmount` and `CommonSendInvoiceData#suggestedTipAmounts` have been added
|
|
||||||
* New type `InputInvoiceMessageContent` has been added
|
|
||||||
* New interface `TextedWithTextSources` on top of `Texted` interface
|
|
||||||
* Interface `TextedInput` now extends `TextedWithTextSources` with overriding of `textSources` field as not
|
|
||||||
nullable
|
|
||||||
* `textSources` become main field in `TextedInput`
|
|
||||||
* **MIGRATION** Remove all `import dev.inmo.tgbotapi.CommonAbstracts.textSources` in your project
|
|
||||||
* `textEntities` become are calculable property in `TextedInput`
|
|
||||||
* Interface `Captioned` and `CaptionedInput` now is deprecated
|
|
||||||
* Most of captions usages were replaced with texts
|
|
||||||
* Interface `Explained` and `ExplainedInput` now is deprecated
|
|
||||||
* Most of captions usages were replaced with texts
|
|
||||||
* Interface `VoiceChatEvent` now is `CommonEvent`
|
|
||||||
* Mechanism of `RawMessageEntity` converting were fully rewritten
|
|
||||||
|
|
||||||
## 0.33.4
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `uuid`: `0.2.3` -> `0.2.4`
|
|
||||||
* `MicroUtils`: `0.4.33` -> `0.4.35`
|
|
||||||
* `Core`:
|
|
||||||
* All `TextSource` implementators have become `Serializable`
|
|
||||||
* New serializer `TextSourceSerializer`
|
|
||||||
* Interface`FromUserMessage` now extends `Message`
|
|
||||||
* New interface `FromUser`
|
|
||||||
* Interface `FromUserMessage` now extends `FromUser`
|
|
||||||
* `Extensions Utils`
|
|
||||||
* Fixes in `parseCommandsWithParams`
|
|
||||||
|
|
||||||
## 0.33.3
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.4.32` -> `0.4.33`
|
|
||||||
* `Ktor`: `1.5.2` -> `1.5.3`
|
|
||||||
* `API`:
|
|
||||||
* Bot actions DSL (fix for [#358](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/358))
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* Rewrite logic of `doInSubContextWithUpdatesFilter` and `doInSubContextWithFlowsUpdatesFilterSetup` extensions
|
|
||||||
* All triggers now work with `stopOnCompletion` set up to `false`
|
|
||||||
|
|
||||||
## 0.33.2
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.4.30` -> `0.4.32`
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* New typealias `MediaGroupFilter` has been added for `MediaGroup` expectators
|
|
||||||
* Several typealiases became `suspend`:
|
|
||||||
* `CallbackQueryMapper`
|
|
||||||
* `ChatMemberUpdatedMapper`
|
|
||||||
* `InlineQueryMapper`
|
|
||||||
* Commands got an additional parameter - `additionalFilter`. It will be called when all command filters were passed
|
|
||||||
|
|
||||||
## 0.33.1
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Kotlin`: `1.4.31` -> `1.4.32`
|
|
||||||
* `MicroUtils`: `0.4.29` -> `0.4.30`
|
|
||||||
* `Klocks`: `2.0.6` -> `2.0.7`
|
|
||||||
* `Utils Extensions`:
|
|
||||||
* Add extensions `parseCommandsWithParams`
|
|
||||||
|
|
||||||
## 0.33.0
|
|
||||||
|
|
||||||
**UPDATE UP TO Telegram Bot API 5.1**
|
|
||||||
_**ALL DEPRECATIONS WERE REMOVED**_
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.4.28` -> `0.4.29`
|
|
||||||
* `Core`:
|
|
||||||
* `AdministratorChatMemberSerializer` and `ChatMemberSerializer` has changed their visibility: they are public for now
|
|
||||||
* Add `ChatInviteLinkRequest` with subrequests like `KnownChatInviteLinkRequest`
|
|
||||||
* Add `CreateChatInviteLink`/`EditChatInviteLink`/`RevokeChatInviteLink` requests
|
|
||||||
* Update `KickChatMember` to include `revokeMessages` flag
|
|
||||||
* Update `PromoteChatMember` to include `canManageVoiceChats` and `canManageChat` flags
|
|
||||||
* Add `ChatInviteLink` object
|
|
||||||
* Add `PrimaryInviteLink` for `ChatInviteLink` with `isPrimary == true`
|
|
||||||
* Add `CommonInviteLink` for `ChatInviteLink` with `isPrimary == false`
|
|
||||||
* `AdministratorChatMemberSerializer` has been set as public for several versions
|
|
||||||
* `ChatMemberSerializer` has been set as public for several versions
|
|
||||||
* Add `ChatMemberUpdated`
|
|
||||||
* Add `MessageAutoDeleteTimerChanged`
|
|
||||||
* Add `VoiceChatEvent`
|
|
||||||
* Add `VoiceChatEnded`
|
|
||||||
* Add `VoiceChatParticipantsInvited`
|
|
||||||
* Add `VoiceChatStarted`
|
|
||||||
* Add `ChatMemberUpdatedUpdate`
|
|
||||||
* Add `CommonChatMemberUpdatedUpdate`
|
|
||||||
* Add `MyChatMemberUpdatedUpdate`
|
|
||||||
* `API`:
|
|
||||||
* All API extensions has been updated
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* Now content triggers and expectators will wait for channel posts too
|
|
||||||
* New waiters and triggers for `ChatMemberUpdated` and its variations
|
|
||||||
|
|
||||||
## 0.32.9
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Kotlin`: `1.4.30` -> `1.4.31`
|
|
||||||
* `Ktor`: `1.5.1` -> `1.5.2`
|
|
||||||
* `MicroUtils`: `0.4.26` -> `0.4.28`
|
|
||||||
* `Coroutines`: `1.4.2` -> `1.4.3`
|
|
||||||
|
|
||||||
## 0.32.8
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Serialization`: `1.1.0-RC` -> `1.1.0`
|
|
||||||
* `MicroUtils`: `0.4.25` -> `0.4.26`
|
|
||||||
|
|
||||||
## 0.32.7
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* New variable `LeftRestrictionsChatPermissions` and `RestrictionsChatPermissions`
|
|
||||||
* `Extensions Utils`:
|
|
||||||
* `DiceAnimationType` class casts
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* Now `doInSubContextWithUpdatesFilter` and `doInSubContext` will automatically subscribe on updates of parent
|
|
||||||
`BehaviourContext`
|
|
||||||
* `doInSubContextWithFlowsUpdatesFilterSetup`, `doInSubContextWithUpdatesFilter` and `doInSubContext` got new
|
|
||||||
parameter `stopOnCompletion` to be able to disable stopping of behaviour context on finishing
|
|
||||||
|
|
||||||
## 0.32.6
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.4.24` -> `0.4.25`
|
|
||||||
* `Extensions API`:
|
|
||||||
* New extension `TelegramBot#replyWithDice`
|
|
||||||
* `Extensions Utils`:
|
|
||||||
* `SlotMachineReelImages` has been renamed to `SlotMachineReelImage`
|
|
||||||
* `SlotMachineReelImage` got two built-in parameters: `text` and `number`
|
|
||||||
* New extension `String#asSlotMachineReelImage`
|
|
||||||
|
|
||||||
## 0.32.5
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* Add `mention` variants for user ids and receiver variants ([#294](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/294))
|
|
||||||
* Now `AbstractRequestCallFactory` will set up one-second delay for zero timeouts in `GetUpdate` requests
|
|
||||||
* Several extensions for `TelegramBotAPI` like `retrieveAccumulatedUpdates` have been added as a solution for
|
|
||||||
[#293](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/293)
|
|
||||||
* Links for `tg://user?id=<user_id>` have been updated ([#292](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/292))
|
|
||||||
* All usages of captions or texts in resends and same things have been replaced with `textSources`
|
|
||||||
* Global `defaultParseMode` has been added ([#291](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/291))
|
|
||||||
|
|
||||||
## 0.32.4
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Kotlin`: `1.4.21` -> `1.4.30`
|
|
||||||
* `Klock`: `2.0.4` -> `2.0.6`
|
|
||||||
* `MicroUtils`: `0.4.23` -> `0.4.24`
|
|
||||||
* `Core`:
|
|
||||||
* Renames:
|
|
||||||
* `ChannelMessage` -> `ChannelContentMessage`
|
|
||||||
* `PublicMessage` -> `PublicContentMessage`
|
|
||||||
* `GroupMessage` -> `GroupContentMessage`
|
|
||||||
* `FromChannelGroupMessage` -> `FromChannelGroupContentMessage`
|
|
||||||
* `AnonymousGroupMessage` -> `AnonymousGroupContentMessage`
|
|
||||||
* `CommonGroupMessage` -> `CommonGroupContentMessage`
|
|
||||||
* `PrivateMessage` -> `PrivateContentMessage`
|
|
||||||
* `Extensions Utils`:
|
|
||||||
* Renames of extensions in `ClassCasts` according to changes in `Core`
|
|
||||||
|
|
||||||
## 0.32.3
|
|
||||||
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* Add expectators and waiters for inline queries
|
|
||||||
|
|
||||||
## 0.32.2
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* Fix of [#275](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/275)
|
|
||||||
|
|
||||||
## 0.32.1
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* Fix of [#272](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/272)
|
|
||||||
* `Utils`:
|
|
||||||
* Fix of [#273](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/273)
|
|
||||||
|
|
||||||
## 0.32.0
|
|
||||||
|
|
||||||
**THIS UPDATE CONTAINS BREAKING CHANGES**
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.4.16` -> `0.4.23`
|
|
||||||
* `Klock`: `0.2.3` -> `0.2.4`
|
|
||||||
* `Ktor`: `1.5.0` -> `1.5.1`
|
|
||||||
* `Core`:
|
|
||||||
* **BREAKING CHANGE** Now `MediaGroupMessage` have a generic type related to `MediaGroupContent`
|
|
||||||
* Methods and types related to `MediaGroupMessage` have been modified according to their meanings
|
|
||||||
* **Important Change** `FlowsUpdatesFilter` now is an interface. Old class has been renamed to
|
|
||||||
`DefaultFlowsUpdatesFilter` and factory method `FlowsUpdatesFilter` has been added
|
|
||||||
* **PASSPORT** Full support of `Telegram Passport API`
|
|
||||||
* `PassportData`
|
|
||||||
* All variants of `EncryptedPassportElement`
|
|
||||||
* All variants of `SecureValue`
|
|
||||||
* All variants of `PassportElementError`
|
|
||||||
* New request `SetPassportDataErrors`
|
|
||||||
* `Credentials`:
|
|
||||||
* `EncryptedCredentials`
|
|
||||||
* `DeryptedCredentials`
|
|
||||||
* `EndDataCredentials`
|
|
||||||
* `Behaviour Builder`:
|
|
||||||
* Trigger and expectation extensions for `MessageContent` (`onContentMessage` and `waitContentMessage`)
|
|
||||||
* `onMediaGroup` has been replaced
|
|
||||||
* `waitMediaGroup` has been added
|
|
||||||
* `onVisualMediaGroup` now is just an alternative to `onVisualGallery`
|
|
||||||
* `command` and `onCommand` expectations has been added for commands `String` variant
|
|
||||||
* New extensions `BehaviourContext#oneOf`, `BehaviourContext#parallel` and `Deferred<T>#withAction`
|
|
||||||
* Several renames:
|
|
||||||
* `waitAudioMediaGroup` -> `waitAudioMediaGroupContent`
|
|
||||||
* `waitDocumentMediaGroup` -> `waitDocumentMediaGroupContent`
|
|
||||||
* `waitMediaGroup` -> `waitAnyMediaGroupContent`
|
|
||||||
* `waitVisualMediaGroup` -> `waitVisualMediaGroupContent`
|
|
||||||
* New extensions `BehaviourContext#waitPassportMessagesWith` and `BehaviourContext#waitAnyPassportMessages`
|
|
||||||
* New extensions `BehaviourContext#onPassportMessage` and `BehaviourContext#onPassportMessageWith`
|
|
||||||
* `Utils`:
|
|
||||||
* New `ClassCasts` for
|
|
||||||
* `Message`
|
|
||||||
* **PASSPORT** `EncryptedPassportElement`
|
|
||||||
* **PASSPORT** `PassportElementError`
|
|
||||||
* **PASSPORT** `SecureValue`
|
|
||||||
* Several tools for decryption have been added:
|
|
||||||
* `AESDecryptor` is available for `JVM` platform
|
|
||||||
* Extensions `EncryptedCredentials#decryptWithPKCS8PrivateKey` are available for `JVM`
|
|
||||||
platform
|
|
||||||
* Extensions `EndDataCredentials#decryptData` and `FileCredentials#decryptFile` have been added
|
|
||||||
* Several extensions `createDecryptor`
|
|
||||||
* Several extensions `doInDecryptionContextWithPKCS8Key`
|
|
||||||
* New extension `Flow#passportMessages`
|
|
||||||
* In most of webhook setting up functions/methods now available parameter `mediaGroupsDebounceTimeMillis`
|
|
||||||
* `API`:
|
|
||||||
* **PASSPORT** New extensions `TelegramBot#setPassportDataErrors`
|
|
||||||
|
|
||||||
## 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`:
|
|
||||||
* `Version`:
|
|
||||||
* `Ktor`: `1.4.1` -> `1.4.2`
|
|
||||||
* `Core`:
|
|
||||||
* New sealed class `SetWebhookRequest` which can be used in `SetWebhook` requests
|
|
||||||
* `Utils`:
|
|
||||||
* Extensions `setWebhookInfoAndStartListenWebhooks` has been united in one extension with `SetWebhookRequest`
|
|
||||||
incoming parameter
|
|
||||||
|
|
||||||
## 0.30.1
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `MicroUtils`: `0.2.7` -> `0.3.0`
|
|
||||||
* `Utils`:
|
|
||||||
* Builder-style DSL for text sources - `buildEntities` (thanks to [djaler](https://github.com/djaler))
|
|
||||||
|
|
||||||
## 0.30.0 Bot API 5.0
|
|
||||||
|
|
||||||
**THIS UPDATE CONTAINS A LOT OF BREAKING CHANGES. PLEASE, BE CAREFUL ON UPGRADING OF YOUR PROJECT**
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* `Version`:
|
|
||||||
* `Coroutine`: `1.4.0` -> `1.4.1`
|
|
||||||
* **NEW** `MicroUtils`: `0.2.7`
|
|
||||||
* `Core`:
|
|
||||||
* Support of `logOut` method (`LogOut` object as a `Request`)
|
|
||||||
* Support of `close` method (`Close` object as a `Request`)
|
|
||||||
* `SetWebhook` updates:
|
|
||||||
* New field `ipAddress`. It works the same as `ip_address` in [setWebhook](https://core.telegram.org/bots/api#setwebhook)
|
|
||||||
section
|
|
||||||
* New field `dropPendingUpdates`. It works the same as `drop_pending_updates` in [setWebhook](https://core.telegram.org/bots/api#setwebhook)
|
|
||||||
section
|
|
||||||
* New field `ExtendedPrivateChat#bio`
|
|
||||||
* New data class `ChatLocation`
|
|
||||||
* New field `UnbanChatMember#onlyIfBanned`
|
|
||||||
* New fields `ExtendedChannelChat#linkedGroupChatId` and `ExtendedSupergroupChat#linkedChannelChatId`
|
|
||||||
* New fields `ExtendedSupergroupChat#location`
|
|
||||||
* New fields `AudioFile#fileName` and `VideoFile#fileName`
|
|
||||||
* New fields `SendDocument#disableContentTypeDetection` and `InputMediaDocument#disableContentTypeDetection`
|
|
||||||
* New request `UnpinAllChatMessages`
|
|
||||||
* New parameter for `unpinChatMessage` method: `messageId`
|
|
||||||
* New dice type `FootballDiceAnimationType`
|
|
||||||
* Limits for dices has been changed
|
|
||||||
* `commonDiceResultLimit` has been deprecated
|
|
||||||
* New field `DiceAnimationType#valueLimits`
|
|
||||||
* Locations updates:
|
|
||||||
* New interface `Headed` with property `heading`
|
|
||||||
* New interface `HorizontallyAccured` with property `horizontalAccuracy`
|
|
||||||
* New interface `ProximityAlertable` with property `proximityAlertRadius`
|
|
||||||
* `Location` class has been separated:
|
|
||||||
* `StaticLocation` for static locations
|
|
||||||
* `LiveLocation` for live locations
|
|
||||||
* Property `Livable#livePeriod` now use typealias type `Seconds` (the same by meaning - `Int`)
|
|
||||||
* `EditLocationMessage` now extends `Locationed`, `HorizontallyAccured`, `ProximityAlertable` and `Headed` interfaces
|
|
||||||
* New properties in `EditChatMessageLiveLocation`: `horizontalAccuracy`, `heading`, `proximityAlertRadius`
|
|
||||||
* New properties in `EditInlineMessageLiveLocation`: `horizontalAccuracy`, `heading`, `proximityAlertRadius`
|
|
||||||
* Main constructor of `SendLocation` now is internal. Instead of that currently available next factories:
|
|
||||||
* `SendLocation` - sending of static location without live parameters
|
|
||||||
* `SendStaticLocation` - sending of static location without live parameters
|
|
||||||
* `SendLiveLocation` - sending of live location with live parameters
|
|
||||||
* `PositionedSendMessageRequest` now extends `Locationed`
|
|
||||||
* `LocationContent#createResend` now can create `LiveLocation`
|
|
||||||
* Support of `ProximityAlertTriggered`. It is `CommonEvent`
|
|
||||||
* Property `pollQuestionTextLength` now have maximum up to `300`
|
|
||||||
* Anonymous Admins:
|
|
||||||
* New field `AdministratorChatMember#isAnonymous`
|
|
||||||
* Several new interfaces of messages:
|
|
||||||
* `SignedMessage` - any message which possibly have `authorSignature`
|
|
||||||
* `WithSenderChatMessage` - any message which have `senderChat`. Property `senderChat` is not-nullable due to
|
|
||||||
separation of implementators
|
|
||||||
* `PublicMessage` - all channel messages have property `val chat: PublicChat` instead of common `val chat: Chat`
|
|
||||||
* `ChannelMessage` - all channel messages have property `val chat: ChannelChat` instead of common `val chat: Chat`
|
|
||||||
* Old `ChannelMessage` was safely renamed to `ChannelMessageImpl` (old name was set as typealias and deprecated)
|
|
||||||
* `GroupMessage` - all group messages have property `val chat: GroupChat` instead of common `val chat: Chat`
|
|
||||||
* `FromChannelGroupMessage` - instances should have property `val channel: ChannelChat`
|
|
||||||
* `AnonymousGroupMessage` - instances may have setup property `authorSignature`
|
|
||||||
* `CommonGroupMessage` - just common message
|
|
||||||
* `PrivateMessage` - works like previous `CommonMessageImpl`
|
|
||||||
* Previous `CommonMessageImpl` safely renamed to `PrivateMessageImpl`
|
|
||||||
* New property `PromoteChatMember#isAnonymous`
|
|
||||||
* Update all classes which must have `entities`/`caption_entities` fields
|
|
||||||
* New request `CopyMessage`
|
|
||||||
* New extension `List<TextSource>#makeString` for more comfortable work with new api with entities
|
|
||||||
* Support for Google Places identifiers for venues
|
|
||||||
* New extensions for text sources separating:
|
|
||||||
* `List<TextSource>#separateForMessage`
|
|
||||||
* `List<TextSource>#separateForCaption`
|
|
||||||
* `List<TextSource>#separateForText`
|
|
||||||
* Rewritten work with text sources and text parts:
|
|
||||||
* Now any `Message` type with entities will have full list of entities. That means that parts without any
|
|
||||||
formatter entities will use `RegularTextSource`
|
|
||||||
* `MultilevelTextSource#textParts` has been deprecated. Now each `MultilevelTextSource` have its own
|
|
||||||
`textSources` list
|
|
||||||
* New dsl for creating of `TextSource` lists
|
|
||||||
* Built-in `handleSafely` and `ExceptionHandler` is deprecated
|
|
||||||
* New common factories for `StorageFile`
|
|
||||||
* `API`:
|
|
||||||
* Extensions `TelegramBot#pinChatMessage` now support any `Chat` and `Message`s from any `Chat`
|
|
||||||
* New extensions `TelegramBot#unpinAllChatMessages`
|
|
||||||
* Extensions `TelegramBot#promoteChatMember` got `isAnonymous` parameter
|
|
||||||
* All old api methods has been actualized to their analogs in `Core`
|
|
||||||
* All `telegramBot` with `token: String` got `apiUrl` parameter
|
|
||||||
* Factory `telegramBotWithCustomClientConfig` has been renamed to `telegramBot`
|
|
||||||
|
|
||||||
## 0.29.4
|
|
||||||
|
|
||||||
* `Core`:
|
|
||||||
* `diceResultLimit` now is deprecated, use `commonDiceResultLimit` instead
|
|
||||||
* New extension `slotMachineDiceResultLimit`
|
|
||||||
* `Utils`:
|
|
||||||
* New enum `SlotMachineReelImages`
|
|
||||||
* New extension `Int#asSlotMachineReelImage`
|
|
||||||
* New data class `SlotMachineResult`
|
|
||||||
* New extension `Dice#calculateSlotMachineResult`
|
|
||||||
|
|
||||||
## 0.29.3
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* Version updates:
|
|
||||||
* `Serialization`: `1.0.0` -> `1.0.1`
|
|
||||||
* `Core`:
|
|
||||||
* New annotation `RiskFeature`. This annotation will be applied to the things which contains unsafe types usage
|
|
||||||
* `SendMediaGroup` factory now marked with `RiskFeature`
|
|
||||||
* Media groups updates:
|
|
||||||
* New functions `SendPlaylist`
|
|
||||||
* New functions `SendDocumentsGroup`
|
|
||||||
* New functions `SendVisualMediaGroup`
|
|
||||||
* New type `VisualMediaGroupMemberInputMedia : MediaGroupMemberInputMedia`
|
|
||||||
* `InputMediaPhoto` now implements `VisualMediaGroupMemberInputMedia` instead of `MediaGroupMemberInputMedia`
|
|
||||||
* `InputMediaVideo` now implements `VisualMediaGroupMemberInputMedia` instead of `MediaGroupMemberInputMedia`
|
|
||||||
* New type `VisualMediaGroupContent : MediaGroupContent`
|
|
||||||
* `PhotoContent` now implements `VisualMediaGroupContent` instead of `MediaGroupContent`
|
|
||||||
* `VideoContent` now implements `VisualMediaGroupContent` instead of `MediaGroupContent`
|
|
||||||
* New type `AudioMediaGroupContent : MediaGroupContent`
|
|
||||||
* `AudioContent` now implements `AudioMediaGroupContent` instead of `MediaContent` and `CaptionedInput`
|
|
||||||
* New type `DocumentMediaGroupContent : MediaGroupContent`
|
|
||||||
* `DocumentContent` now implements `DocumentMediaGroupContent` instead of `MediaContent` and `CaptionedInput`
|
|
||||||
* New type `AudioMediaGroupMemberInputMedia : MediaGroupMemberInputMedia`
|
|
||||||
* `InputMediaAudio` now implements `AudioMediaGroupMemberInputMedia`
|
|
||||||
* New type `DocumentMediaGroupMemberInputMedia : MediaGroupMemberInputMedia`
|
|
||||||
* `InputMediaDocument` now implements `DocumentMediaGroupMemberInputMedia`
|
|
||||||
* New extension `AudioFile#toInputMediaAudio`
|
|
||||||
* `AudioContent` now implements `MediaGroupContent`
|
|
||||||
* New extension `DocumentFile#toInputMediaDocument`
|
|
||||||
* `DocumentContent` now implements `MediaGroupContent`
|
|
||||||
* New dice type `SlotMachineDiceAnimationType`
|
|
||||||
* New extension `TelegramMediaFile#asDocumentFile`
|
|
||||||
* New extension `VideoFile#toInputMediaVideo`
|
|
||||||
* New exception `WrongFileIdentifierException`
|
|
||||||
* Extension `String#toInputMediaFileAttachmentName` now is deprecated
|
|
||||||
* Property `ThumbedInputMedia#thumbMedia` now is deprecated
|
|
||||||
* `API`:
|
|
||||||
* New extensions for media groups:
|
|
||||||
* `TelegramBot#sendPlaylist`
|
|
||||||
* `TelegramBot#replyWithPlaylist`
|
|
||||||
* `TelegramBot#sendDocumentsGroup`
|
|
||||||
* `TelegramBot#replyWithDocumentsGroup`
|
|
||||||
* `TelegramBot#sendVisualMediaGroup`
|
|
||||||
* `TelegramBot#replyWithVisualMediaGroup`
|
|
||||||
* `Utils`:
|
|
||||||
* New extensions for `Flow`s:
|
|
||||||
* `Flow<SentMediaGroupUpdate>#mediaGroupVisualMessages`
|
|
||||||
* `Flow<SentMediaGroupUpdate>#mediaGroupAudioMessages`
|
|
||||||
* `Flow<SentMediaGroupUpdate>#mediaGroupDocumentMessages`
|
|
||||||
* New extensions for `FlowsUpdatesFilter`:
|
|
||||||
* `FlowsUpdatesFilter#audioMessagesWithMediaGroups`
|
|
||||||
* `FlowsUpdatesFilter#mediaGroupAudioMessages`
|
|
||||||
* `FlowsUpdatesFilter#documentMessagesWithMediaGroups`
|
|
||||||
* `FlowsUpdatesFilter#mediaGroupDocumentMessages`
|
|
||||||
* `FlowsUpdatesFilter#mediaGroupVisualMessages`
|
|
||||||
|
|
||||||
## 0.29.2
|
|
||||||
|
|
||||||
* `Common`:
|
|
||||||
* Version updates:
|
|
||||||
* `Coroutines`: `1.3.9` -> `1.4.0`
|
|
||||||
* Internal broadcast channels were replaced with `SharedFlow`
|
|
||||||
* `TelegramBotAPI-extensions-utils`:
|
|
||||||
* Extension `ReceiveChannel#debounceByValue` has been deprecated
|
|
||||||
|
|
||||||
## 0.29.1
|
## 0.29.1
|
||||||
|
|
||||||
* `Common`:
|
* `Common`:
|
||||||
|
|||||||
215
README.md
215
README.md
@@ -1,118 +1,137 @@
|
|||||||
[Participate in our common survey ☺](https://forms.gle/q6Xf8K3fD1pPsYUw9)
|
|
||||||
|
|
||||||
# TelegramBotAPI
|
# TelegramBotAPI
|
||||||
|
|
||||||
Hello! This is a set of libraries for working with Telegram Bot API.
|
| Common info | [](https://github.com/KotlinBy/awesome-kotlin) [](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|
|
||||||
|
|
||||||
| Common info | [](https://github.com/KotlinBy/awesome-kotlin) [](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|
|
|
||||||
| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| Useful links | [](https://t.me/InMoTelegramBotAPI) [](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [](https://tgbotapi.inmo.dev/index.html) [Examples](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/), [Mini tutorial](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
| Useful links | [](https://t.me/InMoTelegramBotAPI) [](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://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
|
| TelegramBotAPI Core status | [](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.core/_latestVersion) [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
|
||||||
| TelegramBotAPI API Extensions status | [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api) |
|
| 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 Util Extensions status | [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils) |
|
| 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://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) |
|
||||||
| TelegramBotAPI All status | [](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) |
|
|
||||||
|
|
||||||
## Examples
|
**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`**
|
||||||
|
|
||||||
There are several things you need to do to launch examples below:
|
|
||||||
|
|
||||||
* Add `mavenCentral()` to your project repositories
|
It is a complex of libraries for working with `TelegramBotAPI` in type-safe and strict way as much as it possible. In
|
||||||
* [Maven variant](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/Including-in-your-project#pomxml)
|
the list of this complex currently next projects:
|
||||||
* Add dependency `implementation "dev.inmo:tgbotapi:$tgbotapi_version"`
|
|
||||||
* Replace `tgbotapi_version` with exact version (see last one in the table above) or put variable with this name in project
|
|
||||||
* Alternative variant for maven [here](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/Including-in-your-project#telegrambotapi)
|
|
||||||
|
|
||||||
More including instructions [available here](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/Including-in-your-project).
|
* [TelegramBotAPI Core](tgbotapi.core/README.md) - core of library. In fact it is independent library and can be used alone
|
||||||
Other configuration examples:
|
without any additional library
|
||||||
|
* [TelegramBotAPI API Extensions](tgbotapi.extensions.api/README.md) - contains extensions (mostly for
|
||||||
|
`RequestsExecutor`), which allows to use the core library in more pleasant way
|
||||||
|
* [TelegramBotAPI Util Extensions](tgbotapi.extensions.utils/README.md) - contains extensions for more comfortable
|
||||||
|
work with commands, updates and other different things
|
||||||
|
* [TelegramBotAPI](tgbotapi/README.md) - concentration of all previously mentioned libraries
|
||||||
|
|
||||||
* [For multiplatform](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/tree/master/ResenderBot)
|
Most part of some specific solves or unuseful
|
||||||
* [For JVM](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/blob/master/GetMeBot/build.gradle)
|
moments are describing by official [Telegram Bot API](https://core.telegram.org/bots/api).
|
||||||
|
|
||||||
### Most common example
|
## JavaScript notes
|
||||||
|
|
||||||
```kotlin
|
### Versions before `0.28.0`
|
||||||
suspend fun main() {
|
|
||||||
val bot = telegramBot(TOKEN)
|
|
||||||
|
|
||||||
bot.buildBehaviour {
|
In case if you are want to use this library inside of browser, you will need additional settings (thanks for help to [Alexander Nozik](https://research.jetbrains.org/researchers/altavir)):
|
||||||
println(getMe())
|
|
||||||
|
<details>
|
||||||
onCommand("start") {
|
<summary>Gradle build script help (for versions before 0.28.0)</summary>
|
||||||
reply(it, "Hi:)")
|
|
||||||
}
|
```groovy
|
||||||
}.join()
|
dependencies {
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
implementation "com.github.insanusmokrassar:TelegramBotAPI:$tgbot_api_version"
|
||||||
|
implementation "com.github.insanusmokrassar:TelegramBotAPI-extensions-api:$tgbot_api_version" // optional
|
||||||
|
implementation "com.github.insanusmokrassar:TelegramBotAPI-extensions-utils:$tgbot_api_version" // optional
|
||||||
|
|
||||||
|
/* Block of dependencies for correct building in browser */
|
||||||
|
implementation(npm("fs"))
|
||||||
|
implementation(npm("bufferutil"))
|
||||||
|
implementation(npm("utf-8-validate"))
|
||||||
|
implementation(npm("abort-controller"))
|
||||||
|
implementation(npm("text-encoding"))
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
In this example you will see information about this bot at the moment of starting and answer with `Hi:)` every time it
|
/* ... */
|
||||||
gets message `/start`
|
|
||||||
|
|
||||||
### Handling only last messages
|
kotlin {
|
||||||
|
target {
|
||||||
```kotlin
|
browser {
|
||||||
suspend fun main() {
|
/* Block for fix of exception in absence of some functionality, https://github.com/ktorio/ktor/issues/1339 */
|
||||||
val bot = telegramBot(TOKEN)
|
dceTask {
|
||||||
|
dceOptions {
|
||||||
val flowsUpdatesFilter = FlowsUpdatesFilter()
|
keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
|
||||||
bot.buildBehaviour(flowUpdatesFilter = flowsUpdatesFilter) {
|
}
|
||||||
println(getMe())
|
}
|
||||||
|
|
||||||
onCommand("start") {
|
|
||||||
reply(it, "Hi:)")
|
|
||||||
}
|
|
||||||
|
|
||||||
retrieveAccumulatedUpdates(this).join()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The main difference with the previous example is that bot will get only last updates (accumulated before bot launch
|
|
||||||
and maybe some updates it got after launch)
|
|
||||||
|
|
||||||
### Build a little bit more complex behaviour
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
suspend fun main() {
|
|
||||||
val bot = telegramBot(TOKEN)
|
|
||||||
|
|
||||||
bot.buildBehaviour {
|
|
||||||
println(getMe())
|
|
||||||
|
|
||||||
val nameReplyMarkup = ReplyKeyboardMarkup(
|
|
||||||
matrix {
|
|
||||||
row {
|
|
||||||
+SimpleKeyboardButton("nope")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
onCommand("start") {
|
|
||||||
val photo = waitPhoto(
|
|
||||||
SendTextMessage(it.chat.id, "Send me your photo please")
|
|
||||||
).first()
|
|
||||||
|
|
||||||
val name = waitText(
|
|
||||||
SendTextMessage(
|
|
||||||
it.chat.id,
|
|
||||||
"Send me your name or choose \"nope\"",
|
|
||||||
replyMarkup = nameReplyMarkup
|
|
||||||
)
|
|
||||||
).first().text.takeIf { it != "nope" }
|
|
||||||
|
|
||||||
sendPhoto(
|
|
||||||
it.chat,
|
|
||||||
photo.mediaCollection,
|
|
||||||
entities = buildEntities {
|
|
||||||
if (name != null) regular(name) // may be collapsed up to name ?.let(::regular)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}.join()
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### More examples
|
</details>
|
||||||
|
|
||||||
You may find examples in [this project](https://github.com/InsanusMokrassar/TelegramBotAPI-examples). Besides, you are
|
## Ok, where should I start?
|
||||||
always welcome in our [wiki](https://github.com/InsanusMokrassar/TelegramBotAPI/wiki/About-this-project) and
|
|
||||||
[chat](https://t.me/InMoTelegramBotAPIChat).
|

|
||||||
|
|
||||||
|
In most cases, the most simple way will be to implement [TelegramBotAPI](TelegramBotAPI/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 API Extensions](tgbotapi.extensions.api/README.md),
|
||||||
|
[TelegramBotAPI Util Extensions](tgbotapi.extensions.utils/README.md) or even
|
||||||
|
[TelegramBotAPI Core](tgbotapi.core/README.md).
|
||||||
|
|
||||||
|
If you want to dive deeper in the core of library or develop something for it - welcome to learn more from
|
||||||
|
[TelegramBotAPI Core](tgbotapi.core/README.md) and our [Telegram Chat](https://teleg.one/InMoTelegramBotAPIChat).
|
||||||
|
|
||||||
|
Anyway, all libraries are very typical inside of them. Examples:
|
||||||
|
|
||||||
|
* In `TelegramBotAPI` common request look like `requestsExecutor.execute(SomeRequest())`
|
||||||
|
* `tgbotapi.extensions.api` typical syntax look like `requestsExecutor.someRequest()` (in most cases it would be
|
||||||
|
better to use `bot` name instead of `requestsExecutor`)
|
||||||
|
* `tgbotapi.extensions.utils` will look like `filter.filterBaseMessageUpdates(chatId).filterExactCommands(Regex("^.*$"))...`
|
||||||
|
|
||||||
|
## Build instruction
|
||||||
|
|
||||||
|
If you want to build this project or to contribute, there are several recommendations:
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
In case if you want to just build project, run next command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew clean build
|
||||||
|
```
|
||||||
|
|
||||||
|
On windows:
|
||||||
|
|
||||||
|
```
|
||||||
|
gradlew.bat clean build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Publishing for work with your version locally
|
||||||
|
|
||||||
|
In case, if you want to work in your other projects using your modification (or some state) of this library,
|
||||||
|
you can use next code:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew clean build publishToMavenLocal
|
||||||
|
```
|
||||||
|
|
||||||
|
On windows:
|
||||||
|
|
||||||
|
```
|
||||||
|
gradlew.bat clean build publishToMavenLocal
|
||||||
|
```
|
||||||
|
|
||||||
|
But you must remember, that in this case your local maven repo must be the first one from
|
||||||
|
your project retrieving libraries:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
repositories {
|
||||||
|
mavenLocal() // that must be the first one
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Besides, for your own version you can change variable `library_version` in the file [gradle.properties](./gradle.properties).
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<minder version="1.11.3">
|
<minder version="1.11.1">
|
||||||
<theme name="default" label="Default" index="-1"/>
|
<theme name="default" label="Default" index="-1"/>
|
||||||
<styles>
|
<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"/>
|
<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,54 +14,45 @@
|
|||||||
<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="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"/>
|
<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>
|
</styles>
|
||||||
<drawarea x="-950.47548925255796" y="-49.650554065281653" scale="0.5"/>
|
<drawarea x="-320.56697591145837" y="-10.028254191080691" scale="0.75"/>
|
||||||
<images/>
|
<images/>
|
||||||
<nodes>
|
<nodes>
|
||||||
<node id="0" posx="1378.798161778599" posy="159.04571601189673" width="472" height="168" side="top" fold="false" treesize="743" layout="Downwards" group="false">
|
<node id="0" posx="748.88964843749955" posy="119.42341613769531" width="472" height="168" side="top" fold="false" treesize="603" 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"/>
|
<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="1394.798161778599" posy="175.04571601189673" maxwidth="488.96484375">
|
<nodename posx="764.88964843749955" posy="135.42341613769531" 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"/>
|
<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>
|
</nodename>
|
||||||
<nodenote></nodenote>
|
<nodenote></nodenote>
|
||||||
<nodes>
|
<nodes>
|
||||||
<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">
|
<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">
|
||||||
<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"/>
|
<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="1427.798161778599" posy="443.04571601189673" maxwidth="419.451171875">
|
<nodename posx="797.88964843749955" posy="403.42341613769531" maxwidth="419.451171875">
|
||||||
<text data="TelegramBotAPI extensions Family of projects which are fully based on TelegramBotAPI and extend its functionality"/>
|
<text data="TelegramBotAPI extensions Family of projects which are fully based on TelegramBotAPI and extend its functionality"/>
|
||||||
</nodename>
|
</nodename>
|
||||||
<nodenote></nodenote>
|
<nodenote></nodenote>
|
||||||
<nodes>
|
<nodes>
|
||||||
<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">
|
<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">
|
||||||
<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"/>
|
<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="1263.298161778599" posy="688.04571601189673" maxwidth="295.90315755208337">
|
<nodename posx="699.38964843749955" posy="648.42341613769531" 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"/>
|
<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>
|
</nodename>
|
||||||
<nodenote></nodenote>
|
<nodenote></nodenote>
|
||||||
</node>
|
</node>
|
||||||
<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">
|
<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">
|
||||||
<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"/>
|
<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="1625.298161778599" posy="688.04571601189673" maxwidth="299.252197265625">
|
<nodename posx="995.38964843749955" posy="648.42341613769531" maxwidth="299.252197265625">
|
||||||
<text data="tgbotapi.extensions.utils Extensions project with utils things which will make easier different operations"/>
|
<text data="tgbotapi.extensions.utils Extensions project with utils things which will make easier different operations"/>
|
||||||
</nodename>
|
</nodename>
|
||||||
<nodenote></nodenote>
|
<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>
|
</node>
|
||||||
</nodes>
|
</nodes>
|
||||||
</node>
|
</node>
|
||||||
</nodes>
|
</nodes>
|
||||||
</node>
|
</node>
|
||||||
<node id="5" posx="1391.8445078072455" posy="1155.6062730594231" width="461" height="236" side="bottom" fold="false" treesize="461" layout="Downwards" group="false">
|
<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="430" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
|
<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="1407.8445078072455" posy="1171.6062730594231" maxwidth="453.885498046875">
|
<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 * tgbotapi.extensions.behaviour_builder">
|
<text data="tgbotapi Here included all available TelegramBotAPI libraries: * tgbotapi.core * tgbotapi.extensions.api * tgbotapi.extensions.utils">
|
||||||
<color>
|
<color>
|
||||||
<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)"/>
|
||||||
@@ -79,94 +70,6 @@
|
|||||||
<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="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)"/>
|
<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)"/>
|
||||||
@@ -199,90 +102,6 @@
|
|||||||
<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="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>
|
</color>
|
||||||
</text>
|
</text>
|
||||||
</nodename>
|
</nodename>
|
||||||
@@ -291,17 +110,12 @@
|
|||||||
</nodes>
|
</nodes>
|
||||||
<groups/>
|
<groups/>
|
||||||
<connections>
|
<connections>
|
||||||
<connection from_id="2" to_id="5" drag_x="1475.8213347929195" drag_y="1014.8259945356604" color="#777777">
|
<connection from_id="2" to_id="4" drag_x="905.70642089843705" drag_y="891.23394775390625" color="#777777">
|
||||||
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||||
<title></title>
|
<title></title>
|
||||||
<note></note>
|
<note></note>
|
||||||
</connection>
|
</connection>
|
||||||
<connection from_id="4" to_id="5" drag_x="1691.5447998046875" drag_y="1107.00439453125" color="#777777">
|
<connection from_id="3" to_id="4" drag_x="1056.456420898437" drag_y="885.48394775390625" 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"/>
|
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
|
||||||
<title></title>
|
<title></title>
|
||||||
<note></note>
|
<note></note>
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="104" height="20">
|
|
||||||
<linearGradient id="b" x2="0" y2="100%">
|
|
||||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
||||||
<stop offset="1" stop-opacity=".1"/>
|
|
||||||
</linearGradient>
|
|
||||||
<clipPath id="a">
|
|
||||||
<rect width="104" height="20" rx="3" fill="#fff"/>
|
|
||||||
</clipPath>
|
|
||||||
<g clip-path="url(#a)">
|
|
||||||
<path fill="#555" d="M0 0h65v20H0z"/>
|
|
||||||
<path fill="#007ec6" d="M35 0h69v20H35z"/>
|
|
||||||
<path fill="url(#b)" d="M0 0h104v20H0z"/>
|
|
||||||
</g>
|
|
||||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
|
|
||||||
<text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Bot</text>
|
|
||||||
<text x="175" y="140" transform="scale(.1)">Bot</text>
|
|
||||||
<text x="690" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Template</text>
|
|
||||||
<text x="690" y="140" transform="scale(.1)">Template</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1016 B |
12
build.gradle
12
build.gradle
@@ -9,6 +9,7 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$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"
|
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,17 +19,6 @@ plugins {
|
|||||||
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" apply false
|
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporal crutch until legacy tests will be stabled or legacy target will be removed
|
|
||||||
allprojects {
|
|
||||||
if (it != rootProject.findProject("docs")) {
|
|
||||||
tasks.whenTaskAdded { task ->
|
|
||||||
if(task.name == "jsLegacyBrowserTest" || task.name == "jsLegacyNodeTest") {
|
|
||||||
task.enabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getCurrentVersionChangelog() {
|
private String getCurrentVersionChangelog() {
|
||||||
OutputStream changelogDataOS = new ByteArrayOutputStream()
|
OutputStream changelogDataOS = new ByteArrayOutputStream()
|
||||||
exec {
|
exec {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ repositories {
|
|||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm()
|
jvm()
|
||||||
js(IR) {
|
js(BOTH) {
|
||||||
browser()
|
browser()
|
||||||
nodejs()
|
nodejs()
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib')
|
implementation kotlin('stdlib')
|
||||||
|
|
||||||
rootProject.subprojects.forEach {
|
project.parent.subprojects.forEach {
|
||||||
if (it != project) {
|
if (it != project) {
|
||||||
api it
|
api it
|
||||||
}
|
}
|
||||||
@@ -46,17 +46,29 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SourceDirectorySet> findSourcesWithName(String... approximateNames) {
|
private Closure includeSourcesInDokka(String... approximateNames) {
|
||||||
return parent.subprojects
|
return {
|
||||||
.findAll { it != project }
|
parent.subprojects.forEach {
|
||||||
.collectMany { it.kotlin.sourceSets }
|
if (it != project) {
|
||||||
.findAll { sourceSet -> approximateNames.any {
|
File srcDir = new File(it.projectDir.absolutePath, "src")
|
||||||
nameToFilter -> sourceSet.name.contains(nameToFilter)
|
if (srcDir.exists() && srcDir.isDirectory()) {
|
||||||
|
srcDir.eachFile { file ->
|
||||||
|
if (approximateNames.any { file.name.contains(it) } && file.isDirectory()) {
|
||||||
|
String pathToSrc = file.absolutePath
|
||||||
|
sourceRoot {
|
||||||
|
path = pathToSrc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.collect { it.kotlin }
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object callback = {
|
dokka {
|
||||||
|
outputFormat = 'html'
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case project.hasProperty("DOKKA_PATH"):
|
case project.hasProperty("DOKKA_PATH"):
|
||||||
outputDirectory = project.property("DOKKA_PATH").toString()
|
outputDirectory = project.property("DOKKA_PATH").toString()
|
||||||
@@ -66,30 +78,19 @@ Object callback = {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
dokkaSourceSets {
|
multiplatform {
|
||||||
configureEach {
|
global {
|
||||||
skipDeprecated.set(true)
|
skipDeprecated = true
|
||||||
|
|
||||||
sourceLink {
|
sourceLink {
|
||||||
localDirectory.set(file("./"))
|
path = "./"
|
||||||
remoteUrl.set(new URL("https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/"))
|
url = "https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/"
|
||||||
remoteLineSuffix.set("#L")
|
lineSuffix = "#L"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
named("commonMain") {
|
common(includeSourcesInDokka("commonMain"))
|
||||||
sourceRoots.setFrom(findSourcesWithName("commonMain"))
|
js(includeSourcesInDokka("jsMain"/*, "commonMain"*/))
|
||||||
}
|
jvm(includeSourcesInDokka("jvmMain"/*, "commonMain"*/))
|
||||||
|
|
||||||
named("jsMain") {
|
|
||||||
sourceRoots.setFrom(findSourcesWithName("jsMain"))
|
|
||||||
}
|
|
||||||
|
|
||||||
named("jvmMain") {
|
|
||||||
sourceRoots.setFrom(findSourcesWithName("jvmMain"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.dokkaGfm(callback)
|
|
||||||
tasks.dokkaHtml(callback)
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
dokka_version=1.4.32
|
dokka_version=0.10.1
|
||||||
|
|
||||||
org.gradle.jvmargs=-Xmx1024m
|
org.gradle.jvmargs=-Xmx1024m
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
org.gradle.jvmargs=-Xmx2048m
|
org.gradle.jvmargs=-Xmx1024m
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
kotlin.js.generate.externals=true
|
kotlin.js.generate.externals=true
|
||||||
kotlin.incremental=true
|
kotlin.incremental=true
|
||||||
kotlin.incremental.js=true
|
kotlin.incremental.js=true
|
||||||
|
|
||||||
kotlin_version=1.5.21
|
kotlin_version=1.4.10
|
||||||
kotlin_coroutines_version=1.5.1
|
kotlin_coroutines_version=1.3.9
|
||||||
kotlin_serialisation_runtime_version=1.2.2
|
kotlin_serialisation_runtime_version=1.0.0
|
||||||
klock_version=2.3.1
|
klock_version=1.12.1
|
||||||
uuid_version=0.3.0
|
uuid_version=0.2.2
|
||||||
ktor_version=1.6.2
|
ktor_version=1.4.1
|
||||||
|
|
||||||
micro_utils_version=0.5.18
|
|
||||||
|
|
||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.35.3
|
library_version=0.29.1
|
||||||
|
|
||||||
|
gradle_bintray_plugin_version=1.8.5
|
||||||
github_release_plugin_version=2.2.12
|
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
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 80 KiB |
@@ -1,20 +1,5 @@
|
|||||||
pluginManagement {
|
|
||||||
resolutionStrategy {
|
|
||||||
eachPlugin {
|
|
||||||
if (requested.id.id == "org.jetbrains.dokka") {
|
|
||||||
useModule("org.jetbrains.dokka:dokka-gradle-plugin:${requested.version}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
repositories {
|
|
||||||
gradlePluginPortal()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
include ":tgbotapi.core"
|
include ":tgbotapi.core"
|
||||||
include ":tgbotapi.extensions.api"
|
include ":tgbotapi.extensions.api"
|
||||||
include ":tgbotapi.extensions.utils"
|
include ":tgbotapi.extensions.utils"
|
||||||
include ":tgbotapi.extensions.behaviour_builder"
|
|
||||||
include ":tgbotapi"
|
include ":tgbotapi"
|
||||||
include ":docs"
|
include ":docs"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# TelegramBotAPI Core
|
# TelegramBotAPI Core
|
||||||
|
|
||||||
|
[ ](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.core/_latestVersion)
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core)
|
[](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core)
|
||||||
|
|
||||||
## What is it?
|
## What is it?
|
||||||
@@ -9,7 +10,10 @@ moments are describing by official [Telegram Bot API](https://core.telegram.org/
|
|||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
This version compatible with [25th of June 2021 update of TelegramBotAPI (version 5.3)](https://core.telegram.org/bots/api-changelog#june-25-2021).
|
This version compatible with [4th of June 2020 update of TelegramBotAPI (version 4.9)](https://core.telegram.org/bots/api#june-4-2020).
|
||||||
|
There is only one exception of implemented functionality - Telegram Passport API, which was presented in
|
||||||
|
[August 2018 update of TelegramBotAPI](https://core.telegram.org/bots/api-changelog#august-27-2018) update. It will be implemented
|
||||||
|
as soon as possible.
|
||||||
|
|
||||||
## How to implement library?
|
## How to implement library?
|
||||||
|
|
||||||
@@ -145,18 +149,3 @@ Here was used `okhttp` realisation of client, but there are several others engin
|
|||||||
available on ktor.io site for [client](https://ktor.io/clients/http-client/engines.html) and [server](https://ktor.io/quickstart/artifacts.html)
|
available on ktor.io site for [client](https://ktor.io/clients/http-client/engines.html) and [server](https://ktor.io/quickstart/artifacts.html)
|
||||||
engines.
|
engines.
|
||||||
|
|
||||||
### Passport
|
|
||||||
|
|
||||||
In case you wish to work with `Telegram Passport`, currently there are several useful things, but most part of working
|
|
||||||
with decryption and handling is available only on JVM. Next snippet contains example of data decryption on JVM platform:
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
passportMessage.passportData.doInDecryptionContextWithPKCS8Key(privateKey) {
|
|
||||||
val passportDataSecureValue = passport ?.data ?: return@doInDecryptionContextWithPKCS8Key
|
|
||||||
val passportData = (passportMessage.passportData.data.firstOrNull { it is CommonPassport } ?: return@doInDecryptionContextWithPKCS8Key) as CommonPassport
|
|
||||||
val decrypted = passportDataSecureValue.decrypt(
|
|
||||||
passportData.data
|
|
||||||
) ?.decodeToString() ?: return@doInDecryptionContextWithPKCS8Key
|
|
||||||
println(decrypted)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||||
|
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradle_bintray_plugin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ repositories {
|
|||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm()
|
jvm()
|
||||||
js(IR) {
|
js(BOTH) {
|
||||||
browser()
|
browser()
|
||||||
nodejs()
|
nodejs()
|
||||||
}
|
}
|
||||||
@@ -46,13 +47,6 @@ kotlin {
|
|||||||
api "com.soywiz.korlibs.klock:klock:$klock_version"
|
api "com.soywiz.korlibs.klock:klock:$klock_version"
|
||||||
api "com.benasher44:uuid:$uuid_version"
|
api "com.benasher44:uuid:$uuid_version"
|
||||||
|
|
||||||
api "dev.inmo:micro_utils.crypto:$micro_utils_version"
|
|
||||||
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
|
|
||||||
api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version"
|
|
||||||
api "dev.inmo:micro_utils.serialization.encapsulator:$micro_utils_version"
|
|
||||||
api "dev.inmo:micro_utils.serialization.typed_serializer:$micro_utils_version"
|
|
||||||
api "dev.inmo:micro_utils.language_codes:$micro_utils_version"
|
|
||||||
|
|
||||||
api "io.ktor:ktor-client-core:$ktor_version"
|
api "io.ktor:ktor-client-core:$ktor_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +54,6 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('test-common')
|
implementation kotlin('test-common')
|
||||||
implementation kotlin('test-annotations-common')
|
implementation kotlin('test-annotations-common')
|
||||||
implementation project(":tgbotapi.extensions.utils")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +72,7 @@ kotlin {
|
|||||||
implementation kotlin('test-junit')
|
implementation kotlin('test-junit')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsTest {
|
jsTest {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('test-junit')
|
implementation kotlin('test-junit')
|
||||||
|
|||||||
53
tgbotapi.core/maven.publish.gradle
Normal file
53
tgbotapi.core/maven.publish.gradle
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
apply plugin: 'maven-publish'
|
||||||
|
|
||||||
|
task javadocsJar(type: Jar) {
|
||||||
|
classifier = 'javadoc'
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
project.publishing.publications.all {
|
||||||
|
// rename artifacts
|
||||||
|
groupId "${project.group}"
|
||||||
|
if (it.name.contains('kotlinMultiplatform')) {
|
||||||
|
artifactId = "${project.name}"
|
||||||
|
} else {
|
||||||
|
artifactId = "${project.name}-$name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Core","description":"Library for Object-Oriented and type-safe work with Telegram Bot API","url":"https://insanusmokrassar.github.io/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}
|
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":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"}]},"type":"Multiplatform"}
|
||||||
@@ -1,69 +1,58 @@
|
|||||||
apply plugin: 'maven-publish'
|
apply plugin: 'com.jfrog.bintray'
|
||||||
apply plugin: 'signing'
|
|
||||||
|
|
||||||
task javadocsJar(type: Jar) {
|
apply from: "maven.publish.gradle"
|
||||||
classifier = 'javadoc'
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
bintray {
|
||||||
publications.all {
|
user = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
|
||||||
artifact javadocsJar
|
key = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
|
||||||
|
filesSpec {
|
||||||
pom {
|
from "${buildDir}/publications/"
|
||||||
description = "Library for Object-Oriented and type-safe work with Telegram Bot API"
|
eachFile {
|
||||||
name = "Telegram Bot API Core"
|
String directorySubname = it.getFile().parentFile.name
|
||||||
url = "https://insanusmokrassar.github.io/TelegramBotAPI"
|
if (it.getName() == "module.json") {
|
||||||
|
if (directorySubname == "kotlinMultiplatform") {
|
||||||
scm {
|
it.setPath("${project.name}/${project.version}/${project.name}-${project.version}.module")
|
||||||
developerConnection = "scm:git:[fetch=]https://github.com/insanusmokrassar/TelegramBotAPI.git[push=]https://github.com/insanusmokrassar/TelegramBotAPI.git"
|
} else {
|
||||||
url = "https://github.com/insanusmokrassar/TelegramBotAPI.git"
|
it.setPath("${project.name}-${directorySubname}/${project.version}/${project.name}-${directorySubname}-${project.version}.module")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
developers {
|
if (directorySubname == "kotlinMultiplatform" && it.getName() == "pom-default.xml") {
|
||||||
|
it.setPath("${project.name}/${project.version}/${project.name}-${project.version}.pom")
|
||||||
developer {
|
} else {
|
||||||
id = "InsanusMokrassar"
|
it.exclude()
|
||||||
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 {
|
into "${project.group}".replace(".", "/")
|
||||||
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
|
}
|
||||||
maven {
|
|
||||||
name = "GithubPackages"
|
publish = true
|
||||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
|
|
||||||
credentials {
|
pkg {
|
||||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
repo = "TelegramBotAPI"
|
||||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
name = "${project.name}"
|
||||||
}
|
vcsUrl = "https://github.com/InsanusMokrassar/TelegramBotAPI"
|
||||||
}
|
licenses = ["Apache-2.0"]
|
||||||
}
|
version {
|
||||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
name = "${project.version}"
|
||||||
maven {
|
released = new Date()
|
||||||
name = "sonatype"
|
vcsTag = "${project.version}"
|
||||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
gpg {
|
||||||
credentials {
|
sign = true
|
||||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
passphrase = project.hasProperty('signing.gnupg.passphrase') ? project.property('signing.gnupg.passphrase') : System.getenv('signing.gnupg.passphrase')
|
||||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signing {
|
bintrayUpload.doFirst {
|
||||||
useGpgCmd()
|
publications = publishing.publications.collect {
|
||||||
sign publishing.publications
|
if (it.name.contains('kotlinMultiplatform')) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
it.name
|
||||||
|
}
|
||||||
|
} - null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bintrayUpload.dependsOn publishToMavenLocal
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package dev.inmo.tgbotapi.CommonAbstracts
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
|
import dev.inmo.tgbotapi.utils.fullListOfSubSource
|
||||||
|
|
||||||
|
interface Captioned {
|
||||||
|
val caption: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CaptionedOutput : Captioned {
|
||||||
|
val parseMode: ParseMode?
|
||||||
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
*/
|
||||||
|
val captionEntities: List<TextPart>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert its [CaptionedInput.captionEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
|
||||||
|
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||||
|
*/
|
||||||
|
fun CaptionedInput.fullEntitiesList(): FullTextSourcesList = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList()
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.payments.abstracts.Currencied
|
|
||||||
import dev.inmo.tgbotapi.types.payments.abstracts.Priced
|
|
||||||
|
|
||||||
interface CommonSendInvoiceData : Titled, Currencied, Priced {
|
|
||||||
val description: String
|
|
||||||
val payload: String
|
|
||||||
val providerToken: String
|
|
||||||
val maxTipAmount: Int?
|
|
||||||
val suggestedTipAmounts: List<Int>?
|
|
||||||
val providerData: String?
|
|
||||||
val requireName: Boolean
|
|
||||||
val requirePhoneNumber: Boolean
|
|
||||||
val requireEmail: Boolean
|
|
||||||
val requireShippingAddress: Boolean
|
|
||||||
val shouldSendPhoneNumberToProvider: Boolean
|
|
||||||
val shouldSendEmailToProvider: Boolean
|
|
||||||
val priceDependOnShipAddress: Boolean
|
|
||||||
|
|
||||||
val photoUrl: String?
|
|
||||||
val photoSize: Long?
|
|
||||||
val photoWidth: Int?
|
|
||||||
val photoHeight: Int?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun setPhoto(
|
|
||||||
photoUrl: String,
|
|
||||||
photoSize: Long? = null,
|
|
||||||
photoWidth: Int? = null,
|
|
||||||
photoHeight: Int? = null
|
|
||||||
)
|
|
||||||
|
|
||||||
fun unsetPhoto()
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
package dev.inmo.tgbotapi.CommonAbstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
|
|
||||||
interface CommonVenueData : Titled {
|
interface CommonVenueData : Titled {
|
||||||
override val title: String
|
override val title: String
|
||||||
val address: String
|
val address: String
|
||||||
val foursquareId: FoursquareId?
|
val foursquareId: String?
|
||||||
val foursquareType: FoursquareType? // TODO:: Rewrite with enum or interface
|
val foursquareType: String? // TODO:: Rewrite with enum or interface
|
||||||
val googlePlaceId: GooglePlaceId?
|
|
||||||
val googlePlaceType: GooglePlaceType?
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package dev.inmo.tgbotapi.CommonAbstracts
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
|
import dev.inmo.tgbotapi.utils.fullListOfSubSource
|
||||||
|
|
||||||
|
interface Explained {
|
||||||
|
val explanation: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExplainedOutput : Explained {
|
||||||
|
val parseMode: ParseMode?
|
||||||
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
*/
|
||||||
|
val explanationEntities: List<TextPart>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert its [ExplainedInput.explanationEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource]
|
||||||
|
* with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource]
|
||||||
|
*/
|
||||||
|
fun ExplainedInput.fullEntitiesList(): FullTextSourcesList = explanation ?.fullListOfSubSource(explanationEntities) ?.map { it.source } ?: emptyList()
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.User
|
|
||||||
|
|
||||||
interface FromUser {
|
|
||||||
val user: User
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.Degrees
|
|
||||||
|
|
||||||
interface Headed {
|
|
||||||
val heading: Degrees?
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.Meters
|
|
||||||
|
|
||||||
interface HorizontallyAccured {
|
|
||||||
val horizontalAccuracy: Meters?
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
package dev.inmo.tgbotapi.CommonAbstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.Seconds
|
|
||||||
|
|
||||||
interface Livable {
|
interface Livable {
|
||||||
/**
|
/**
|
||||||
* Period in [Seconds]
|
* Period in SECONDS
|
||||||
*/
|
*/
|
||||||
val livePeriod: Seconds?
|
val livePeriod: Int?
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.Meters
|
|
||||||
|
|
||||||
interface ProximityAlertable {
|
|
||||||
val proximityAlertRadius: Meters?
|
|
||||||
}
|
|
||||||
@@ -1,79 +1,23 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
package dev.inmo.tgbotapi.CommonAbstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
|
typealias FullTextSourcesList = List<TextSource>
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.MultilevelTextSource
|
typealias FullTextPartsList = List<TextPart>
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.separateForCaption
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.separateForMessage
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.separateForText
|
|
||||||
import dev.inmo.tgbotapi.types.captionLength
|
|
||||||
import dev.inmo.tgbotapi.types.textLength
|
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
|
|
||||||
const val DirectInvocationOfTextSourceConstructor =
|
interface TextSource {
|
||||||
"It is strongly not recommended to use constructors directly instead of factory methods"
|
val asMarkdownSource: String
|
||||||
|
val asMarkdownV2Source: String
|
||||||
|
val asHtmlSource: String
|
||||||
|
val source: String
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated(
|
|
||||||
"Replaced",
|
interface MultilevelTextSource : TextSource {
|
||||||
ReplaceWith("TextSourcesList", "dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList")
|
val textParts: List<TextPart>
|
||||||
|
}
|
||||||
|
|
||||||
|
data class TextPart(
|
||||||
|
val range: IntRange,
|
||||||
|
val source: TextSource
|
||||||
)
|
)
|
||||||
typealias TextSourcesList = TextSourcesList
|
|
||||||
|
|
||||||
@Deprecated("Replaced", ReplaceWith("TextSource", "dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource"))
|
fun List<TextPart>.justTextSources() = map { it.source }
|
||||||
typealias TextSource = TextSource
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
@Deprecated("Replaced", ReplaceWith("plus", "dev.inmo.tgbotapi.types.MessageEntity.textsources.plus"))
|
|
||||||
inline operator fun TextSource.plus(other: TextSource) =
|
|
||||||
listOf(this, other)
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
@Deprecated("Replaced", ReplaceWith("plus", "dev.inmo.tgbotapi.types.MessageEntity.textsources.plus"))
|
|
||||||
inline operator fun TextSource.plus(other: List<TextSource>) =
|
|
||||||
listOf(this) + other
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
@Deprecated("Replaced", ReplaceWith("plus", "dev.inmo.tgbotapi.types.MessageEntity.textsources.plus"))
|
|
||||||
inline operator fun TextSource.plus(text: String) =
|
|
||||||
listOf(this, regular(text))
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
@Deprecated("Replaced", ReplaceWith("plus", "dev.inmo.tgbotapi.types.MessageEntity.textsources.plus"))
|
|
||||||
inline operator fun List<TextSource>.plus(text: String) = this + regular(text)
|
|
||||||
|
|
||||||
@Deprecated(
|
|
||||||
"Replaced",
|
|
||||||
ReplaceWith("MultilevelTextSource", "dev.inmo.tgbotapi.types.MessageEntity.textsources.MultilevelTextSource")
|
|
||||||
)
|
|
||||||
typealias MultilevelTextSource = MultilevelTextSource
|
|
||||||
|
|
||||||
@Deprecated("Replaced", ReplaceWith("makeString()", "dev.inmo.tgbotapi.utils.extensions.makeString"))
|
|
||||||
fun List<TextSource>.makeString() = makeString()
|
|
||||||
|
|
||||||
@Deprecated(
|
|
||||||
"Replaced",
|
|
||||||
ReplaceWith("separateForMessage", "dev.inmo.tgbotapi.types.MessageEntity.textsources.separateForMessage")
|
|
||||||
)
|
|
||||||
fun List<TextSource>.separateForMessage(limit: IntRange, numberOfParts: Int? = null) =
|
|
||||||
separateForMessage(limit, numberOfParts)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will prepare [TextSource]s list for messages. Remember, that first part will be separated with
|
|
||||||
* [captionLength] and all others with
|
|
||||||
*/
|
|
||||||
@Deprecated(
|
|
||||||
"Replaced",
|
|
||||||
ReplaceWith("separateForCaption", "dev.inmo.tgbotapi.types.MessageEntity.textsources.separateForCaption")
|
|
||||||
)
|
|
||||||
fun List<TextSource>.separateForCaption() = separateForCaption()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will prepare [TextSource]s list for messages with [textLength]
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
@Deprecated(
|
|
||||||
"Replaced",
|
|
||||||
ReplaceWith("separateForText", "dev.inmo.tgbotapi.types.MessageEntity.textsources.separateForText")
|
|
||||||
)
|
|
||||||
inline fun List<TextSource>.separateForText() = separateForText()
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.CommonAbstracts
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
|
||||||
|
|
||||||
interface Texted {
|
|
||||||
val text: String?
|
|
||||||
}
|
|
||||||
interface TextedWithTextSources : Texted {
|
|
||||||
/**
|
|
||||||
* Full list of [TextSource]s
|
|
||||||
*/
|
|
||||||
val textSources: List<TextSource>?
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ParsableOutput : Texted {
|
|
||||||
val parseMode: ParseMode?
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EntitiesOutput : TextedWithTextSources {
|
|
||||||
val entities: List<TextSource>?
|
|
||||||
get() = textSources
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TextedOutput : ParsableOutput, EntitiesOutput
|
|
||||||
|
|
||||||
interface TextedInput : TextedWithTextSources {
|
|
||||||
override val textSources: List<TextSource>
|
|
||||||
}
|
|
||||||
@@ -4,5 +4,4 @@ import dev.inmo.tgbotapi.types.MessageIdentifier
|
|||||||
|
|
||||||
interface ReplyMessageId {
|
interface ReplyMessageId {
|
||||||
val replyToMessageId: MessageIdentifier?
|
val replyToMessageId: MessageIdentifier?
|
||||||
val allowSendingWithoutReply: Boolean?
|
|
||||||
}
|
}
|
||||||
@@ -1,58 +1,30 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor
|
package dev.inmo.tgbotapi.bot.Ktor
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.safely
|
|
||||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||||
import dev.inmo.tgbotapi.bot.Ktor.base.*
|
import dev.inmo.tgbotapi.bot.Ktor.base.*
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.EmptyLimiter
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.types.Response
|
import dev.inmo.tgbotapi.types.Response
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.features.*
|
import io.ktor.client.features.*
|
||||||
|
import io.ktor.client.statement.HttpStatement
|
||||||
import io.ktor.client.statement.readText
|
import io.ktor.client.statement.readText
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class KtorRequestsExecutorBuilder(
|
|
||||||
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
|
||||||
) {
|
|
||||||
var client: HttpClient = HttpClient()
|
|
||||||
var callsFactories: List<KtorCallFactory> = emptyList()
|
|
||||||
var excludeDefaultFactories: Boolean = false
|
|
||||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
|
|
||||||
var jsonFormatter: Json = nonstrictJsonFormat
|
|
||||||
|
|
||||||
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun telegramBot(
|
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
|
||||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
|
||||||
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shortcut for [telegramBot]
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
inline fun telegramBot(
|
|
||||||
token: String,
|
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
|
||||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
|
||||||
|
|
||||||
class KtorRequestsExecutor(
|
class KtorRequestsExecutor(
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
client: HttpClient = HttpClient(),
|
client: HttpClient = HttpClient(),
|
||||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||||
excludeDefaultFactories: Boolean = false,
|
excludeDefaultFactories: Boolean = false,
|
||||||
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
|
private val requestsLimiter: RequestLimiter = EmptyLimiter,
|
||||||
private val jsonFormatter: Json = nonstrictJsonFormat
|
private val jsonFormatter: Json = nonstrictJsonFormat
|
||||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||||
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
||||||
if (!excludeDefaultFactories) {
|
if (!excludeDefaultFactories) {
|
||||||
this + listOf(SimpleRequestCallFactory(), MultipartRequestCallFactory(), DownloadFileRequestCallFactory)
|
this + listOf(SimpleRequestCallFactory, MultipartRequestCallFactory, DownloadFileRequestCallFactory)
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
@@ -65,10 +37,10 @@ class KtorRequestsExecutor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun <T : Any> execute(request: Request<T>): T {
|
override suspend fun <T : Any> execute(request: Request<T>): T {
|
||||||
return safely(
|
return handleSafely(
|
||||||
{ e ->
|
{ e ->
|
||||||
throw if (e is ClientRequestException) {
|
throw if (e is ClientRequestException) {
|
||||||
val content = e.response.readText()
|
val content = e.response ?.readText() ?: throw e
|
||||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||||
newRequestException(
|
newRequestException(
|
||||||
responseObject,
|
responseObject,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
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.Ktor.KtorCallFactory
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||||
import dev.inmo.tgbotapi.requests.GetUpdates
|
import dev.inmo.tgbotapi.requests.GetUpdates
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.types.Response
|
import dev.inmo.tgbotapi.types.Response
|
||||||
|
import dev.inmo.tgbotapi.types.RetryAfterError
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.call.receive
|
import io.ktor.client.call.receive
|
||||||
@@ -13,11 +13,10 @@ import io.ktor.client.features.timeout
|
|||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.ktor.client.statement.HttpResponse
|
import io.ktor.client.statement.HttpResponse
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
var defaultUpdateTimeoutForZeroDelay = 1000L
|
|
||||||
|
|
||||||
abstract class AbstractRequestCallFactory : KtorCallFactory {
|
abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||||
private val methodsCache: MutableMap<String, String> = mutableMapOf()
|
private val methodsCache: MutableMap<String, String> = mutableMapOf()
|
||||||
override suspend fun <T : Any> makeCall(
|
override suspend fun <T : Any> makeCall(
|
||||||
@@ -43,11 +42,6 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
|||||||
requestTimeoutMillis = customTimeoutMillis
|
requestTimeoutMillis = customTimeoutMillis
|
||||||
socketTimeoutMillis = customTimeoutMillis
|
socketTimeoutMillis = customTimeoutMillis
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
timeout {
|
|
||||||
requestTimeoutMillis = defaultUpdateTimeoutForZeroDelay
|
|
||||||
socketTimeoutMillis = defaultUpdateTimeoutForZeroDelay
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,17 +51,23 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
|||||||
val content = response.receive<String>()
|
val content = response.receive<String>()
|
||||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||||
|
|
||||||
return safely {
|
return (responseObject.result?.let {
|
||||||
(responseObject.result?.let {
|
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
|
||||||
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
|
} ?: responseObject.parameters?.let {
|
||||||
} ?: response.let {
|
val error = it.error
|
||||||
throw newRequestException(
|
if (error is RetryAfterError) {
|
||||||
responseObject,
|
delay(error.leftToRetry)
|
||||||
content,
|
makeCall(client, urlsKeeper, request, jsonFormatter)
|
||||||
"Can't get result object from $content"
|
} else {
|
||||||
)
|
null
|
||||||
})
|
}
|
||||||
}
|
} ?: response.let {
|
||||||
|
throw newRequestException(
|
||||||
|
responseObject,
|
||||||
|
content,
|
||||||
|
"Can't get result object from $content"
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
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.Ktor.KtorCallFactory
|
||||||
|
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||||
import dev.inmo.tgbotapi.requests.DownloadFile
|
import dev.inmo.tgbotapi.requests.DownloadFile
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
|
import dev.inmo.tgbotapi.utils.handleSafely
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.client.statement.*
|
||||||
|
import io.ktor.http.HttpMethod
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
object DownloadFileRequestCallFactory : KtorCallFactory {
|
object DownloadFileRequestCallFactory : KtorCallFactory {
|
||||||
@@ -18,7 +21,7 @@ object DownloadFileRequestCallFactory : KtorCallFactory {
|
|||||||
): T? = (request as? DownloadFile) ?.let {
|
): T? = (request as? DownloadFile) ?.let {
|
||||||
val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}"
|
val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}"
|
||||||
|
|
||||||
return safely {
|
return handleSafely {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
client.get<ByteArray>(fullUrl) as T // always ByteArray
|
client.get<ByteArray>(fullUrl) as T // always ByteArray
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
package dev.inmo.tgbotapi.bot.Ktor.base
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import dev.inmo.tgbotapi.utils.mapWithCommonValues
|
import dev.inmo.tgbotapi.utils.mapWithCommonValues
|
||||||
@@ -10,7 +9,7 @@ import io.ktor.client.request.forms.formData
|
|||||||
import io.ktor.http.Headers
|
import io.ktor.http.Headers
|
||||||
import io.ktor.http.HttpHeaders
|
import io.ktor.http.HttpHeaders
|
||||||
|
|
||||||
class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
object MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
||||||
override fun <T : Any> prepareCallBody(
|
override fun <T : Any> prepareCallBody(
|
||||||
client: HttpClient,
|
client: HttpClient,
|
||||||
urlsKeeper: TelegramAPIUrlsKeeper,
|
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
@@ -26,9 +25,10 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
|||||||
Headers.build {
|
Headers.build {
|
||||||
append(HttpHeaders.ContentType, value.mimeType)
|
append(HttpHeaders.ContentType, value.mimeType)
|
||||||
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
||||||
},
|
}
|
||||||
block = value.file::input
|
) {
|
||||||
)
|
value.file.asInput()
|
||||||
|
}
|
||||||
is FileId -> append(key, value.fileId)
|
is FileId -> append(key, value.fileId)
|
||||||
else -> append(key, value.toString())
|
else -> append(key, value.toString())
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,4 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Deprecated("Use class MultipartRequestCallFactory() constructor call instead of just MultipartRequestCallFactory")
|
|
||||||
companion object : KtorCallFactory by MultipartRequestCallFactory()
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
package dev.inmo.tgbotapi.bot.Ktor.base
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.http.content.TextContent
|
import io.ktor.http.content.TextContent
|
||||||
|
|
||||||
class SimpleRequestCallFactory : AbstractRequestCallFactory() {
|
object SimpleRequestCallFactory : AbstractRequestCallFactory() {
|
||||||
override fun <T : Any> prepareCallBody(
|
override fun <T : Any> prepareCallBody(
|
||||||
client: HttpClient,
|
client: HttpClient,
|
||||||
urlsKeeper: TelegramAPIUrlsKeeper,
|
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
@@ -20,7 +19,4 @@ class SimpleRequestCallFactory : AbstractRequestCallFactory() {
|
|||||||
ContentType.Application.Json
|
ContentType.Application.Json
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Deprecated("Use class SimpleRequestCallFactory() constructor call instead of just SimpleRequestCallFactory")
|
|
||||||
companion object : KtorCallFactory by SimpleRequestCallFactory()
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.bot.exceptions
|
package dev.inmo.tgbotapi.bot.exceptions
|
||||||
|
|
||||||
import com.soywiz.klock.DateTime
|
|
||||||
import dev.inmo.tgbotapi.types.Response
|
import dev.inmo.tgbotapi.types.Response
|
||||||
import dev.inmo.tgbotapi.types.RetryAfterError
|
|
||||||
import io.ktor.utils.io.errors.IOException
|
import io.ktor.utils.io.errors.IOException
|
||||||
|
|
||||||
fun newRequestException(
|
fun newRequestException(
|
||||||
@@ -12,25 +10,11 @@ fun newRequestException(
|
|||||||
cause: Throwable? = null
|
cause: Throwable? = null
|
||||||
) = response.description ?.let { description ->
|
) = response.description ?.let { description ->
|
||||||
when {
|
when {
|
||||||
description == "Bad Request: reply message not found" || description == "Bad Request: replied message not found" -> ReplyMessageNotFoundException(response, plainAnswer, message, cause)
|
description == "Bad Request: reply message not found" -> ReplyMessageNotFoundException(response, plainAnswer, message, cause)
|
||||||
description == "Bad Request: message to edit not found" -> MessageToEditNotFoundException(response, plainAnswer, message, cause)
|
description == "Bad Request: message to edit not found" -> MessageToEditNotFoundException(response, plainAnswer, message, cause)
|
||||||
description.contains("Bad Request: message is not modified") -> MessageIsNotModifiedException(response, plainAnswer, message, cause)
|
description.contains("Bad Request: message is not modified") -> MessageIsNotModifiedException(response, plainAnswer, message, cause)
|
||||||
description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause)
|
description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause)
|
||||||
description.contains("PHOTO_INVALID_DIMENSIONS") -> InvalidPhotoDimensionsException(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
|
|
||||||
)
|
|
||||||
description.contains("Conflict: terminated by other getUpdates request") -> GetUpdatesConflict(
|
|
||||||
response,
|
|
||||||
plainAnswer,
|
|
||||||
message,
|
|
||||||
cause
|
|
||||||
)
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
||||||
@@ -61,12 +45,3 @@ class MessageToEditNotFoundException(response: Response, plainAnswer: String, me
|
|||||||
|
|
||||||
class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
||||||
RequestException(response, plainAnswer, message, cause)
|
RequestException(response, plainAnswer, message, cause)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
class GetUpdatesConflict(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
|
||||||
RequestException(response, plainAnswer, message, cause)
|
|
||||||
|
|||||||
@@ -1,41 +1,67 @@
|
|||||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||||
|
|
||||||
import com.soywiz.klock.DateTime
|
import com.soywiz.klock.DateTime
|
||||||
import dev.inmo.tgbotapi.types.MilliSeconds
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.sync.Semaphore
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.Transient
|
|
||||||
import kotlin.math.roundToLong
|
|
||||||
|
|
||||||
private fun now(): Long = DateTime.nowUnixLong()
|
private fun now(): Long = DateTime.nowUnixLong()
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class CommonLimiter(
|
class CommonLimiter(
|
||||||
private val lockCount: Int = 10,
|
private val lockCount: Int = 10,
|
||||||
private val regenTime: MilliSeconds = 15 * 1000, // 15 seconds for full regen of opportunity to send message
|
private val regenTime: Long = 20 * 1000L // 20 seconds for full regen of opportunity to send message
|
||||||
@Transient
|
|
||||||
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
|
||||||
) : RequestLimiter {
|
) : RequestLimiter {
|
||||||
@Transient
|
private var doLimit: Boolean = false
|
||||||
private val quotaSemaphore = Semaphore(lockCount)
|
|
||||||
@Transient
|
private val counterChannel = Channel<Unit>(Channel.UNLIMITED)
|
||||||
private val counterRegeneratorJob = scope.launch {
|
private val scope = CoroutineScope(Dispatchers.Default)
|
||||||
val regenDelay: MilliSeconds = (regenTime.toDouble() / lockCount).roundToLong()
|
private val counterJob = scope.launch {
|
||||||
while (isActive) {
|
var wasLastSecond = 0
|
||||||
delay(regenDelay)
|
var lastCountTime = now()
|
||||||
if (quotaSemaphore.availablePermits < lockCount) {
|
var limitManagementJob: Job? = null
|
||||||
try {
|
var removeLimitTime: Long = lastCountTime
|
||||||
quotaSemaphore.release()
|
for (counter in counterChannel) {
|
||||||
} catch (_: IllegalStateException) {
|
val now = now()
|
||||||
// Skip IllegalStateException due to the fact that this exception may happens in release method
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 {
|
override suspend fun <T> limit(block: suspend () -> T): T {
|
||||||
quotaSemaphore.acquire()
|
counterChannel.send(Unit)
|
||||||
return block()
|
return if (!doLimit) {
|
||||||
|
block()
|
||||||
|
} else {
|
||||||
|
quoterChannel.receive()
|
||||||
|
block()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package dev.inmo.tgbotapi.bot.settings.limiters
|
||||||
|
|
||||||
|
object EmptyLimiter : RequestLimiter {
|
||||||
|
override suspend fun <T> limit(block: suspend () -> T): T = block()
|
||||||
|
}
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
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 }
|
|
||||||
var throwable: Throwable? = null
|
|
||||||
val result = safely({
|
|
||||||
throwable = when (it) {
|
|
||||||
is TooMuchRequestsException -> {
|
|
||||||
lock(it.retryAfter.leftToRetry)
|
|
||||||
it
|
|
||||||
}
|
|
||||||
is ClientRequestException -> {
|
|
||||||
if (it.response.status == HttpStatusCode.TooManyRequests) {
|
|
||||||
lock(defaultTooManyRequestsDelay)
|
|
||||||
} else {
|
|
||||||
throw it
|
|
||||||
}
|
|
||||||
it
|
|
||||||
}
|
|
||||||
else -> throw it
|
|
||||||
}
|
|
||||||
null
|
|
||||||
}) {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
if (throwable == null) {
|
|
||||||
return result!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.bot.settings.limiters
|
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.*
|
||||||
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
@@ -11,60 +9,62 @@ import kotlin.math.pow
|
|||||||
|
|
||||||
private sealed class RequestEvent
|
private sealed class RequestEvent
|
||||||
private class AddRequest(
|
private class AddRequest(
|
||||||
val continuation: Continuation<MilliSeconds>
|
val continuation: Continuation<Long>
|
||||||
) : RequestEvent()
|
) : RequestEvent()
|
||||||
private object CompleteRequest : RequestEvent()
|
private object CompleteRequest : RequestEvent()
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PowLimiter(
|
data class PowLimiter(
|
||||||
private val minAwaitTime: MilliSeconds = 0L,
|
private val minAwaitTime: Long = 0L,
|
||||||
private val maxAwaitTime: MilliSeconds = 10000L,
|
private val maxAwaitTime: Long = 10000L,
|
||||||
private val powValue: Double = 4.0,
|
private val powValue: Double = 4.0,
|
||||||
private val powK: Double = 1.6,
|
private val powK: Double = 0.0016
|
||||||
@Transient
|
|
||||||
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
|
||||||
) : RequestLimiter {
|
) : RequestLimiter {
|
||||||
@Transient
|
@Transient
|
||||||
private val awaitTimeRange = minAwaitTime .. maxAwaitTime
|
private val scope = CoroutineScope(Dispatchers.Default)
|
||||||
@Transient
|
@Transient
|
||||||
private val eventsChannel = let {
|
private val eventsChannel = Channel<RequestEvent>(Channel.UNLIMITED)
|
||||||
var requestsInWork = 0.0
|
@Transient
|
||||||
scope.actor<RequestEvent> {
|
private val awaitTimeRange = minAwaitTime .. maxAwaitTime
|
||||||
when (it) {
|
|
||||||
is AddRequest -> {
|
|
||||||
val awaitTime = (requestsInWork.pow(powValue) * powK).toLong()
|
|
||||||
requestsInWork++
|
|
||||||
|
|
||||||
it.continuation.resume(
|
init {
|
||||||
when {
|
scope.launch {
|
||||||
awaitTime in awaitTimeRange -> awaitTime
|
var requestsInWork: Double = 0.0
|
||||||
awaitTime < awaitTimeRange.first -> awaitTimeRange.first
|
for (event in eventsChannel) {
|
||||||
else -> awaitTimeRange.last
|
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--
|
||||||
}
|
}
|
||||||
is CompleteRequest -> requestsInWork--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|
||||||
safely { block() }
|
|
||||||
} finally {
|
|
||||||
eventsChannel.send(CompleteRequest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun <T> limit(
|
override suspend fun <T> limit(
|
||||||
block: suspend () -> T
|
block: suspend () -> T
|
||||||
): T {
|
): T {
|
||||||
return withDelay(block)
|
val delayMillis = suspendCoroutine<Long> {
|
||||||
|
scope.launch { eventsChannel.send(AddRequest(it)) }
|
||||||
|
}
|
||||||
|
delay(delayMillis)
|
||||||
|
return try {
|
||||||
|
block()
|
||||||
|
} finally {
|
||||||
|
eventsChannel.send(CompleteRequest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import dev.inmo.tgbotapi.types.passport.PassportElementError
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import kotlinx.serialization.builtins.serializer
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SetPassportDataErrors(
|
|
||||||
@SerialName(userIdField)
|
|
||||||
val user: UserId,
|
|
||||||
@SerialName(errorsField)
|
|
||||||
val errors: List<PassportElementError>
|
|
||||||
) : SimpleRequest<Boolean> {
|
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
|
||||||
get() = Boolean.serializer()
|
|
||||||
override fun method(): String = "setPassportDataErrors"
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.polls.Poll
|
import dev.inmo.tgbotapi.types.polls.Poll
|
||||||
import dev.inmo.tgbotapi.types.polls.PollSerializer
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -20,7 +19,7 @@ data class StopPoll(
|
|||||||
) : MessageAction, SimpleRequest<Poll>, ReplyMarkup {
|
) : MessageAction, SimpleRequest<Poll>, ReplyMarkup {
|
||||||
override fun method(): String = "stopPoll"
|
override fun method(): String = "stopPoll"
|
||||||
override val resultDeserializer: DeserializationStrategy<Poll>
|
override val resultDeserializer: DeserializationStrategy<Poll>
|
||||||
get() = PollSerializer
|
get() = Poll.serializer()
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.requests.abstracts
|
package dev.inmo.tgbotapi.requests.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaFileAttachmentName
|
||||||
import dev.inmo.tgbotapi.utils.StorageFile
|
import dev.inmo.tgbotapi.utils.StorageFile
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.descriptors.*
|
import kotlinx.serialization.descriptors.*
|
||||||
import kotlinx.serialization.encoding.Decoder
|
import kotlinx.serialization.encoding.Decoder
|
||||||
import kotlinx.serialization.encoding.Encoder
|
import kotlinx.serialization.encoding.Encoder
|
||||||
@@ -13,14 +12,6 @@ sealed class InputFile {
|
|||||||
abstract val fileId: String
|
abstract val fileId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline val InputFile.attachFileId
|
|
||||||
get() = "attach://$fileId"
|
|
||||||
internal inline val InputFile.fileIdToSend
|
|
||||||
get() = when (this) {
|
|
||||||
is FileId -> fileId
|
|
||||||
is MultipartFile -> attachFileId
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:: add checks for file url/file id regex
|
// TODO:: add checks for file url/file id regex
|
||||||
/**
|
/**
|
||||||
* Contains file id or file url
|
* Contains file id or file url
|
||||||
@@ -32,13 +23,19 @@ data class FileId(
|
|||||||
|
|
||||||
fun String.toInputFile() = FileId(this)
|
fun String.toInputFile() = FileId(this)
|
||||||
|
|
||||||
@RiskFeature
|
@Serializer(InputFile::class)
|
||||||
object InputFileSerializer : KSerializer<InputFile> {
|
internal object InputFileSerializer : KSerializer<InputFile> {
|
||||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(FileId::class.toString(), PrimitiveKind.STRING)
|
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(FileId::class.toString(), PrimitiveKind.STRING)
|
||||||
override fun serialize(encoder: Encoder, value: InputFile) = encoder.encodeString(value.fileId)
|
override fun serialize(encoder: Encoder, value: InputFile) = encoder.encodeString(value.fileId)
|
||||||
override fun deserialize(decoder: Decoder): FileId = FileId(decoder.decodeString())
|
override fun deserialize(decoder: Decoder): FileId = FileId(decoder.decodeString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val InputFile.asMediaData: String
|
||||||
|
get() = when (this) {
|
||||||
|
is FileId -> fileId
|
||||||
|
is MultipartFile -> fileId.toInputMediaFileAttachmentName()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:: add checks for files size
|
// TODO:: add checks for files size
|
||||||
/**
|
/**
|
||||||
* Contains info about file for sending
|
* Contains info about file for sending
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ data class AnswerCallbackQuery(
|
|||||||
val showAlert: Boolean? = null,
|
val showAlert: Boolean? = null,
|
||||||
@SerialName(urlField)
|
@SerialName(urlField)
|
||||||
val url: String? = null,
|
val url: String? = null,
|
||||||
@SerialName(cacheTimeField)
|
@SerialName(cachedTimeField)
|
||||||
val cachedTimeSeconds: Int? = null
|
val cachedTimeSeconds: Int? = null
|
||||||
) : SimpleRequest<Boolean> {
|
) : SimpleRequest<Boolean> {
|
||||||
override fun method(): String = "answerCallbackQuery"
|
override fun method(): String = "answerCallbackQuery"
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.serializers.InlineQueryResultSerializer
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.serializers.InlineQueryResultSerializer
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
|
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
@@ -17,7 +16,7 @@ data class AnswerInlineQuery(
|
|||||||
@Serializable(InlineQueryAnswersResultsSerializer::class)
|
@Serializable(InlineQueryAnswersResultsSerializer::class)
|
||||||
@SerialName(resultsField)
|
@SerialName(resultsField)
|
||||||
val results: List<InlineQueryResult> = emptyList(),
|
val results: List<InlineQueryResult> = emptyList(),
|
||||||
@SerialName(cacheTimeField)
|
@SerialName(cachedTimeField)
|
||||||
val cachedTime: Int? = null,
|
val cachedTime: Int? = null,
|
||||||
@SerialName(isPersonalField)
|
@SerialName(isPersonalField)
|
||||||
val isPersonal: Boolean? = null,
|
val isPersonal: Boolean? = null,
|
||||||
@@ -27,7 +26,7 @@ data class AnswerInlineQuery(
|
|||||||
val switchPmText: String? = null,
|
val switchPmText: String? = null,
|
||||||
@SerialName(switchPmParameterField)
|
@SerialName(switchPmParameterField)
|
||||||
val switchPmParameter: String? = null
|
val switchPmParameter: String? = null
|
||||||
) : SimpleRequest<Boolean> {
|
): SimpleRequest<Boolean> {
|
||||||
override fun method(): String = "answerInlineQuery"
|
override fun method(): String = "answerInlineQuery"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
get() = Boolean.serializer()
|
get() = Boolean.serializer()
|
||||||
@@ -52,7 +51,6 @@ fun InlineQuery.createAnswer(
|
|||||||
switchPmParameter
|
switchPmParameter
|
||||||
)
|
)
|
||||||
|
|
||||||
@RiskFeature
|
internal object InlineQueryAnswersResultsSerializer: KSerializer<List<InlineQueryResult>> by ListSerializer(
|
||||||
object InlineQueryAnswersResultsSerializer : KSerializer<List<InlineQueryResult>> by ListSerializer(
|
|
||||||
InlineQueryResultSerializer
|
InlineQueryResultSerializer
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import dev.inmo.tgbotapi.requests.answers.payments.abstracts.AnswerShippingQuery
|
|||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.payments.ShippingOption
|
import dev.inmo.tgbotapi.types.payments.ShippingOption
|
||||||
import dev.inmo.tgbotapi.types.payments.ShippingQuery
|
import dev.inmo.tgbotapi.types.payments.ShippingQuery
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
|
|
||||||
@@ -22,8 +21,7 @@ data class AnswerShippingQueryOk(
|
|||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RiskFeature
|
internal object ShippingOptionsSerializer : KSerializer<List<ShippingOption>> by ListSerializer(
|
||||||
object ShippingOptionsSerializer : KSerializer<List<ShippingOption>> by ListSerializer(
|
|
||||||
ShippingOption.serializer()
|
ShippingOption.serializer()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.bot
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|
||||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
|
||||||
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
|
||||||
|
|
||||||
sealed interface MyCommandsRequest<T : Any> : SimpleRequest<T>, WithOptionalLanguageCode {
|
|
||||||
val scope: BotCommandScope
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.bot
|
|
||||||
|
|
||||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
|
||||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
|
||||||
import dev.inmo.tgbotapi.types.commands.*
|
|
||||||
import dev.inmo.tgbotapi.types.languageCodeField
|
|
||||||
import dev.inmo.tgbotapi.types.scopeField
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import kotlinx.serialization.builtins.serializer
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class DeleteMyCommands(
|
|
||||||
@SerialName(scopeField)
|
|
||||||
@Serializable(BotCommandScopeSerializer::class)
|
|
||||||
override val scope: BotCommandScope = BotCommandScopeDefault,
|
|
||||||
@SerialName(languageCodeField)
|
|
||||||
@Serializable(IetfLanguageCodeSerializer::class)
|
|
||||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
|
||||||
) : MyCommandsRequest<Boolean> {
|
|
||||||
override fun method(): String = "deleteMyCommands"
|
|
||||||
override val requestSerializer: SerializationStrategy<DeleteMyCommands> = serializer()
|
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean> = Boolean.serializer()
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
scope: BotCommandScope = BotCommandScopeDefault,
|
|
||||||
languageCode: String?
|
|
||||||
) : this(
|
|
||||||
scope,
|
|
||||||
languageCode ?.let(::IetfLanguageCode)
|
|
||||||
)
|
|
||||||
|
|
||||||
companion object : MyCommandsRequest<Boolean> by DeleteMyCommands()
|
|
||||||
}
|
|
||||||
@@ -1,36 +1,17 @@
|
|||||||
package dev.inmo.tgbotapi.requests.bot
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
import dev.inmo.tgbotapi.types.BotCommand
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import dev.inmo.tgbotapi.types.commands.*
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
|
|
||||||
private val getMyCommandsSerializer = ListSerializer(BotCommand.serializer())
|
private val getMyCommandsSerializer = ListSerializer(BotCommand.serializer())
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class GetMyCommands(
|
object GetMyCommands : SimpleRequest<List<BotCommand>> {
|
||||||
@SerialName(scopeField)
|
|
||||||
@Serializable(BotCommandScopeSerializer::class)
|
|
||||||
override val scope: BotCommandScope = BotCommandScopeDefault,
|
|
||||||
@SerialName(languageCodeField)
|
|
||||||
@Serializable(IetfLanguageCodeSerializer::class)
|
|
||||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
|
||||||
) : MyCommandsRequest<List<BotCommand>> {
|
|
||||||
override fun method(): String = "getMyCommands"
|
override fun method(): String = "getMyCommands"
|
||||||
override val resultDeserializer: DeserializationStrategy<List<BotCommand>>
|
override val resultDeserializer: DeserializationStrategy<List<BotCommand>>
|
||||||
get() = getMyCommandsSerializer
|
get() = getMyCommandsSerializer
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|
||||||
constructor(
|
|
||||||
scope: BotCommandScope = BotCommandScopeDefault,
|
|
||||||
languageCode: String?
|
|
||||||
) : this(
|
|
||||||
scope,
|
|
||||||
languageCode ?.let(::IetfLanguageCode)
|
|
||||||
)
|
|
||||||
|
|
||||||
companion object : MyCommandsRequest<List<BotCommand>> by GetMyCommands()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,21 @@
|
|||||||
package dev.inmo.tgbotapi.requests.bot
|
package dev.inmo.tgbotapi.requests.bot
|
||||||
|
|
||||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.commands.*
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class SetMyCommands(
|
class SetMyCommands(
|
||||||
@SerialName(botCommandsField)
|
@SerialName(botCommandsField)
|
||||||
val commands: List<BotCommand>,
|
val commands: List<BotCommand>
|
||||||
@SerialName(scopeField)
|
) : SimpleRequest<Boolean> {
|
||||||
@Serializable(BotCommandScopeSerializer::class)
|
|
||||||
override val scope: BotCommandScope = BotCommandScopeDefault,
|
|
||||||
@SerialName(languageCodeField)
|
|
||||||
@Serializable(IetfLanguageCodeSerializer::class)
|
|
||||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
|
||||||
) : MyCommandsRequest<Boolean> {
|
|
||||||
override fun method(): String = "setMyCommands"
|
override fun method(): String = "setMyCommands"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
get() = Boolean.serializer()
|
get() = Boolean.serializer()
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|
||||||
constructor(
|
|
||||||
commands: List<BotCommand>,
|
|
||||||
scope: BotCommandScope = BotCommandScopeDefault,
|
|
||||||
languageCode: String?
|
|
||||||
) : this(
|
|
||||||
commands,
|
|
||||||
scope,
|
|
||||||
languageCode ?.let(::IetfLanguageCode)
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (commands.size !in botCommandsLimit) {
|
if (commands.size !in botCommandsLimit) {
|
||||||
error("Bot commands list size able to be in range $botCommandsLimit, but incoming size is ${commands.size}")
|
error("Bot commands list size able to be in range $botCommandsLimit, but incoming size is ${commands.size}")
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.chat.abstracts
|
|
||||||
|
|
||||||
import com.soywiz.klock.DateTime
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
|
||||||
|
|
||||||
interface ChatInviteLinkRequest : SimpleRequest<CommonInviteLink> {
|
|
||||||
val chatId: ChatIdentifier
|
|
||||||
|
|
||||||
override val resultDeserializer: DeserializationStrategy<CommonInviteLink>
|
|
||||||
get() = CommonInviteLink.serializer()
|
|
||||||
}
|
|
||||||
interface KnownChatInviteLinkRequest : ChatInviteLinkRequest {
|
|
||||||
val inviteLink: String
|
|
||||||
}
|
|
||||||
interface EditChatInviteLinkRequest : ChatInviteLinkRequest {
|
|
||||||
val expireDate: DateTime?
|
|
||||||
val membersLimit: MembersLimit?
|
|
||||||
}
|
|
||||||
@@ -4,13 +4,13 @@ import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMember
|
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMember
|
||||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMemberSerializer
|
import dev.inmo.tgbotapi.types.ChatMember.abstracts.AdministratorChatMemberSerializerWithoutDeserialization
|
||||||
import dev.inmo.tgbotapi.types.chatIdField
|
import dev.inmo.tgbotapi.types.chatIdField
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
|
|
||||||
private val chatMembersListSerializer = ListSerializer(
|
private val chatMembersListSerializer = ListSerializer(
|
||||||
AdministratorChatMemberSerializer
|
AdministratorChatMemberSerializerWithoutDeserialization
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|||||||
@@ -8,16 +8,13 @@ import kotlinx.serialization.*
|
|||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class GetChatMemberCount(
|
data class GetChatMembersCount(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier
|
override val chatId: ChatIdentifier
|
||||||
): ChatRequest, SimpleRequest<Int> {
|
): ChatRequest, SimpleRequest<Int> {
|
||||||
override fun method(): String = "getChatMemberCount"
|
override fun method(): String = "getChatMembersCount"
|
||||||
override val resultDeserializer: DeserializationStrategy<Int>
|
override val resultDeserializer: DeserializationStrategy<Int>
|
||||||
get() = Int.serializer()
|
get() = Int.serializer()
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Renamed", ReplaceWith("GetChatMemberCount", "dev.inmo.tgbotapi.requests.chat.get.GetChatMemberCount"))
|
|
||||||
typealias GetChatMembersCount = GetChatMemberCount
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.chat.invite_links
|
|
||||||
|
|
||||||
import com.soywiz.klock.DateTime
|
|
||||||
import dev.inmo.tgbotapi.requests.chat.abstracts.EditChatInviteLinkRequest
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class CreateChatInviteLink(
|
|
||||||
@SerialName(chatIdField)
|
|
||||||
override val chatId: ChatIdentifier,
|
|
||||||
@SerialName(expireDateField)
|
|
||||||
private val expirationUnixTimeStamp: TelegramDate? = null,
|
|
||||||
@SerialName(memberLimitField)
|
|
||||||
override val membersLimit: MembersLimit? = null
|
|
||||||
) : EditChatInviteLinkRequest {
|
|
||||||
override val expireDate: DateTime?
|
|
||||||
get() = expirationUnixTimeStamp ?.asDate
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
|
|
||||||
override fun method(): String = "createChatInviteLink"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun CreateChatInviteLink(
|
|
||||||
chatId: ChatId,
|
|
||||||
expireDate: DateTime,
|
|
||||||
membersLimit: MembersLimit? = null
|
|
||||||
): CreateChatInviteLink = CreateChatInviteLink(
|
|
||||||
chatId, expireDate.toTelegramDate(), membersLimit
|
|
||||||
)
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.chat.invite_links
|
|
||||||
|
|
||||||
import com.soywiz.klock.DateTime
|
|
||||||
import dev.inmo.tgbotapi.requests.chat.abstracts.EditChatInviteLinkRequest
|
|
||||||
import dev.inmo.tgbotapi.requests.chat.abstracts.KnownChatInviteLinkRequest
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class EditChatInviteLink(
|
|
||||||
@SerialName(chatIdField)
|
|
||||||
override val chatId: ChatIdentifier,
|
|
||||||
@SerialName(inviteLinkField)
|
|
||||||
override val inviteLink: String,
|
|
||||||
@SerialName(expireDateField)
|
|
||||||
private val expirationUnixTimeStamp: TelegramDate? = null,
|
|
||||||
@SerialName(memberLimitField)
|
|
||||||
override val membersLimit: MembersLimit? = null
|
|
||||||
) : EditChatInviteLinkRequest, KnownChatInviteLinkRequest {
|
|
||||||
override val expireDate: DateTime?
|
|
||||||
get() = expirationUnixTimeStamp ?.asDate
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
|
|
||||||
override fun method(): String = "editChatInviteLink"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun EditChatInviteLink(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
inviteLink: String,
|
|
||||||
expireDate: DateTime,
|
|
||||||
membersLimit: MembersLimit? = null
|
|
||||||
): EditChatInviteLink = EditChatInviteLink(
|
|
||||||
chatId, inviteLink, expireDate.toTelegramDate(), membersLimit
|
|
||||||
)
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.chat.invite_links
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.chat.abstracts.KnownChatInviteLinkRequest
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class RevokeChatInviteLink(
|
|
||||||
@SerialName(chatIdField)
|
|
||||||
override val chatId: ChatIdentifier,
|
|
||||||
@SerialName(inviteLinkField)
|
|
||||||
override val inviteLink: String
|
|
||||||
) : KnownChatInviteLinkRequest {
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
|
|
||||||
override fun method(): String = "revokeChatInviteLink"
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.requests.chat.members
|
|||||||
import dev.inmo.tgbotapi.requests.chat.abstracts.ChatMemberRequest
|
import dev.inmo.tgbotapi.requests.chat.abstracts.ChatMemberRequest
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
|
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMember
|
||||||
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMemberSerializer
|
import dev.inmo.tgbotapi.types.ChatMember.abstracts.ChatMemberDeserializationStrategy
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -15,7 +15,7 @@ data class GetChatMember(
|
|||||||
) : ChatMemberRequest<ChatMember> {
|
) : ChatMemberRequest<ChatMember> {
|
||||||
override fun method(): String = "getChatMember"
|
override fun method(): String = "getChatMember"
|
||||||
override val resultDeserializer: DeserializationStrategy<ChatMember>
|
override val resultDeserializer: DeserializationStrategy<ChatMember>
|
||||||
get() = ChatMemberSerializer
|
get() = ChatMemberDeserializationStrategy
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,17 @@ import kotlinx.serialization.*
|
|||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BanChatMember(
|
data class KickChatMember(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(userIdField)
|
@SerialName(userIdField)
|
||||||
override val userId: UserId,
|
override val userId: UserId,
|
||||||
@SerialName(untilDateField)
|
@SerialName(untilDateField)
|
||||||
override val untilDate: TelegramDate? = null,
|
override val untilDate: TelegramDate? = null
|
||||||
@SerialName(revokeMessagesField)
|
|
||||||
val revokeMessages: Boolean? = null
|
|
||||||
) : ChatMemberRequest<Boolean>, UntilDate {
|
) : ChatMemberRequest<Boolean>, UntilDate {
|
||||||
override fun method(): String = "banChatMember"
|
override fun method(): String = "kickChatMember"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
get() = Boolean.serializer()
|
get() = Boolean.serializer()
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Renamed", ReplaceWith("BanChatMember", "dev.inmo.tgbotapi.requests.chat.members.BanChatMember"))
|
|
||||||
typealias KickChatMember = BanChatMember
|
|
||||||
@@ -14,8 +14,6 @@ data class PromoteChatMember(
|
|||||||
override val userId: UserId,
|
override val userId: UserId,
|
||||||
@SerialName(untilDateField)
|
@SerialName(untilDateField)
|
||||||
override val untilDate: TelegramDate? = null,
|
override val untilDate: TelegramDate? = null,
|
||||||
@SerialName(isAnonymousField)
|
|
||||||
private val isAnonymous: Boolean? = null,
|
|
||||||
@SerialName(canChangeInfoField)
|
@SerialName(canChangeInfoField)
|
||||||
private val canChangeInfo: Boolean? = null,
|
private val canChangeInfo: Boolean? = null,
|
||||||
@SerialName(canPostMessagesField)
|
@SerialName(canPostMessagesField)
|
||||||
@@ -31,11 +29,7 @@ data class PromoteChatMember(
|
|||||||
@SerialName(canPinMessagesField)
|
@SerialName(canPinMessagesField)
|
||||||
private val canPinMessages: Boolean? = null,
|
private val canPinMessages: Boolean? = null,
|
||||||
@SerialName(canPromoteMembersField)
|
@SerialName(canPromoteMembersField)
|
||||||
private val canPromoteMembers: Boolean? = null,
|
private val canPromoteMembers: Boolean? = null
|
||||||
@SerialName(canManageVoiceChatsField)
|
|
||||||
private val canManageVoiceChats: Boolean? = null,
|
|
||||||
@SerialName(canManageChatField)
|
|
||||||
private val canManageChat: Boolean? = null
|
|
||||||
) : ChatMemberRequest<Boolean>, UntilDate {
|
) : ChatMemberRequest<Boolean>, UntilDate {
|
||||||
override fun method(): String = "promoteChatMember"
|
override fun method(): String = "promoteChatMember"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ data class UnbanChatMember(
|
|||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(userIdField)
|
@SerialName(userIdField)
|
||||||
override val userId: UserId,
|
override val userId: UserId
|
||||||
@SerialName(onlyIfBannedField)
|
|
||||||
val onlyIfBanned: Boolean? = null
|
|
||||||
) : ChatMemberRequest<Boolean> {
|
) : ChatMemberRequest<Boolean> {
|
||||||
override fun method(): String = "unbanChatMember"
|
override fun method(): String = "unbanChatMember"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private chat, the bot
|
|
||||||
* must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a
|
|
||||||
* supergroup or 'can_edit_messages' admin right in a channel.
|
|
||||||
*/
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PinChatMessage (
|
data class PinChatMessage (
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ data class SetChatPhoto (
|
|||||||
override fun method(): String = "setChatPhoto"
|
override fun method(): String = "setChatPhoto"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
get() = Boolean.serializer()
|
get() = Boolean.serializer()
|
||||||
@Transient
|
|
||||||
override val mediaMap: Map<String, MultipartFile> = mapOf(photoField to photo)
|
override val mediaMap: Map<String, MultipartFile> = mapOf(photoField to photo)
|
||||||
@Transient
|
|
||||||
override val paramsJson: JsonObject = toJson(serializer())
|
override val paramsJson: JsonObject = toJson(serializer())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
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.chatIdField
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import kotlinx.serialization.builtins.serializer
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an
|
|
||||||
* administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or
|
|
||||||
* 'can_edit_messages' admin right in a channel.
|
|
||||||
*
|
|
||||||
* @see PinChatMessage
|
|
||||||
* @see UnpinChatMessage
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
data class UnpinAllChatMessages(
|
|
||||||
@SerialName(chatIdField)
|
|
||||||
override val chatId: ChatIdentifier
|
|
||||||
): ChatRequest, SimpleRequest<Boolean> {
|
|
||||||
override fun method(): String = "unpinAllChatMessages"
|
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
|
||||||
get() = Boolean.serializer()
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
}
|
|
||||||
@@ -2,16 +2,15 @@ package dev.inmo.tgbotapi.requests.chat.modify
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
import dev.inmo.tgbotapi.CommonAbstracts.types.ChatRequest
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.chatIdField
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class UnpinChatMessage(
|
data class UnpinChatMessage(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier
|
||||||
@SerialName(messageIdField)
|
|
||||||
val messageId: MessageIdentifier? = null
|
|
||||||
): ChatRequest, SimpleRequest<Boolean> {
|
): ChatRequest, SimpleRequest<Boolean> {
|
||||||
override fun method(): String = "unpinChatMessage"
|
override fun method(): String = "unpinChatMessage"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
|||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.LocationContent
|
import dev.inmo.tgbotapi.types.message.content.LocationContent
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>()
|
private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>()
|
||||||
const val editMessageLiveLocationMethod = "editMessageLiveLocation"
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class EditChatMessageLiveLocation(
|
data class EditChatMessageLiveLocation(
|
||||||
@@ -22,24 +20,12 @@ data class EditChatMessageLiveLocation(
|
|||||||
override val latitude: Double,
|
override val latitude: Double,
|
||||||
@SerialName(longitudeField)
|
@SerialName(longitudeField)
|
||||||
override val longitude: Double,
|
override val longitude: Double,
|
||||||
@SerialName(horizontalAccuracyField)
|
|
||||||
override val horizontalAccuracy: Meters? = null,
|
|
||||||
@SerialName(headingField)
|
|
||||||
override val heading: Degrees? = null,
|
|
||||||
@SerialName(proximityAlertRadiusField)
|
|
||||||
override val proximityAlertRadius: Meters? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditChatMessage<LocationContent>, EditReplyMessage, EditLocationMessage {
|
) : EditChatMessage<LocationContent>, EditReplyMessage, EditLocationMessage {
|
||||||
override fun method(): String = editMessageLiveLocationMethod
|
override fun method(): String = "editMessageLiveLocation"
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
||||||
get() = commonResultDeserializer
|
get() = commonResultDeserializer
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|
||||||
init {
|
|
||||||
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
|
|
||||||
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package dev.inmo.tgbotapi.requests.edit.LiveLocation
|
|||||||
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -14,22 +13,10 @@ data class EditInlineMessageLiveLocation(
|
|||||||
override val latitude: Double,
|
override val latitude: Double,
|
||||||
@SerialName(longitudeField)
|
@SerialName(longitudeField)
|
||||||
override val longitude: Double,
|
override val longitude: Double,
|
||||||
@SerialName(horizontalAccuracyField)
|
|
||||||
override val horizontalAccuracy: Meters? = null,
|
|
||||||
@SerialName(headingField)
|
|
||||||
override val heading: Degrees? = null,
|
|
||||||
@SerialName(proximityAlertRadiusField)
|
|
||||||
override val proximityAlertRadius: Meters? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditInlineMessage, EditReplyMessage, EditLocationMessage {
|
) : EditInlineMessage, EditReplyMessage, EditLocationMessage {
|
||||||
override fun method(): String = editMessageLiveLocationMethod
|
override fun method(): String = "editMessageLiveLocation"
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|
||||||
init {
|
|
||||||
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
|
|
||||||
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import dev.inmo.tgbotapi.types.message.content.LocationContent
|
|||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>()
|
private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>()
|
||||||
const val stopMessageLiveLocationMethod = "stopMessageLiveLocation"
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class StopChatMessageLiveLocation(
|
data class StopChatMessageLiveLocation(
|
||||||
@@ -21,7 +20,7 @@ data class StopChatMessageLiveLocation(
|
|||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditChatMessage<LocationContent>, EditReplyMessage {
|
) : EditChatMessage<LocationContent>, EditReplyMessage {
|
||||||
override fun method(): String = stopMessageLiveLocationMethod
|
override fun method(): String = "stopMessageLiveLocation"
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
||||||
get() = commonResultDeserializer
|
get() = commonResultDeserializer
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ data class StopInlineMessageLiveLocation(
|
|||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditInlineMessage, EditReplyMessage {
|
) : EditInlineMessage, EditReplyMessage {
|
||||||
override fun method(): String = stopMessageLiveLocationMethod
|
override fun method(): String = "stopMessageLiveLocation"
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.requests.edit.abstracts
|
package dev.inmo.tgbotapi.requests.edit.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
interface EditLocationMessage {
|
||||||
|
val latitude: Double
|
||||||
interface EditLocationMessage : Locationed, HorizontallyAccured, ProximityAlertable, Headed
|
val longitude: Double
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.requests.edit.abstracts
|
package dev.inmo.tgbotapi.requests.edit.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
|
|
||||||
interface EditTextChatMessage : TextedOutput {
|
interface EditTextChatMessage {
|
||||||
override val text: String
|
val text: String
|
||||||
|
val parseMode: ParseMode?
|
||||||
}
|
}
|
||||||
@@ -3,49 +3,17 @@ package dev.inmo.tgbotapi.requests.edit.caption
|
|||||||
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.edit.media.MediaContentMessageResultDeserializer
|
import dev.inmo.tgbotapi.requests.edit.media.MediaContentMessageResultDeserializer
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
const val editMessageCaptionMethod = "editMessageCaption"
|
const val editMessageCaptionMethod = "editMessageCaption"
|
||||||
|
|
||||||
fun EditChatMessageCaption(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
messageId: MessageIdentifier,
|
|
||||||
text: String,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditChatMessageCaption(
|
|
||||||
chatId,
|
|
||||||
messageId,
|
|
||||||
text,
|
|
||||||
parseMode,
|
|
||||||
null,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun EditChatMessageCaption(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
messageId: MessageIdentifier,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditChatMessageCaption(
|
|
||||||
chatId,
|
|
||||||
messageId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class EditChatMessageCaption internal constructor(
|
data class EditChatMessageCaption(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(messageIdField)
|
@SerialName(messageIdField)
|
||||||
@@ -54,14 +22,9 @@ data class EditChatMessageCaption internal constructor(
|
|||||||
override val text: String,
|
override val text: String,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditChatMessage<MediaContent>, EditTextChatMessage, EditReplyMessage {
|
) : EditChatMessage<MediaContent>, EditTextChatMessage, EditReplyMessage {
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = editMessageCaptionMethod
|
override fun method(): String = editMessageCaptionMethod
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<MediaContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<MediaContent>>
|
||||||
|
|||||||
@@ -2,56 +2,22 @@ package dev.inmo.tgbotapi.requests.edit.caption
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
fun EditInlineMessageCaption(
|
|
||||||
inlineMessageId: InlineMessageIdentifier,
|
|
||||||
text: String,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditInlineMessageCaption(
|
|
||||||
inlineMessageId,
|
|
||||||
text,
|
|
||||||
parseMode,
|
|
||||||
null,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun EditInlineMessageCaption(
|
|
||||||
inlineMessageId: InlineMessageIdentifier,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditInlineMessageCaption(
|
|
||||||
inlineMessageId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class EditInlineMessageCaption internal constructor(
|
data class EditInlineMessageCaption(
|
||||||
@SerialName(inlineMessageIdField)
|
@SerialName(inlineMessageIdField)
|
||||||
override val inlineMessageId: InlineMessageIdentifier,
|
override val inlineMessageId: InlineMessageIdentifier,
|
||||||
@SerialName(captionField)
|
@SerialName(captionField)
|
||||||
override val text: String,
|
override val text: String,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage {
|
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage {
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = editMessageCaptionMethod
|
override fun method(): String = editMessageCaptionMethod
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|||||||
@@ -3,53 +3,17 @@ package dev.inmo.tgbotapi.requests.edit.text
|
|||||||
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.TextContentMessageResultDeserializer
|
import dev.inmo.tgbotapi.requests.send.TextContentMessageResultDeserializer
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
const val editMessageTextMethod = "editMessageText"
|
const val editMessageTextMethod = "editMessageText"
|
||||||
|
|
||||||
fun EditChatMessageText(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
messageId: MessageIdentifier,
|
|
||||||
text: String,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
disableWebPagePreview: Boolean? = null,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditChatMessageText(
|
|
||||||
chatId,
|
|
||||||
messageId,
|
|
||||||
text,
|
|
||||||
parseMode,
|
|
||||||
null,
|
|
||||||
disableWebPagePreview,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun EditChatMessageText(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
messageId: MessageIdentifier,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
disableWebPagePreview: Boolean? = null,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditChatMessageText(
|
|
||||||
chatId,
|
|
||||||
messageId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
disableWebPagePreview,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class EditChatMessageText internal constructor(
|
data class EditChatMessageText(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(messageIdField)
|
@SerialName(messageIdField)
|
||||||
@@ -58,16 +22,11 @@ data class EditChatMessageText internal constructor(
|
|||||||
override val text: String,
|
override val text: String,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(entitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(disableWebPagePreviewField)
|
@SerialName(disableWebPagePreviewField)
|
||||||
override val disableWebPagePreview: Boolean? = null,
|
override val disableWebPagePreview: Boolean? = null,
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditChatMessage<TextContent>, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
|
) : EditChatMessage<TextContent>, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = editMessageTextMethod
|
override fun method(): String = editMessageTextMethod
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>
|
||||||
|
|||||||
@@ -1,64 +1,27 @@
|
|||||||
package dev.inmo.tgbotapi.requests.edit.text
|
package dev.inmo.tgbotapi.requests.edit.text
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
import dev.inmo.tgbotapi.requests.edit.abstracts.*
|
||||||
|
import dev.inmo.tgbotapi.requests.edit.media.editMessageMediaMethod
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
fun EditInlineMessageText(
|
|
||||||
inlineMessageId: InlineMessageIdentifier,
|
|
||||||
text: String,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
disableWebPagePreview: Boolean? = null,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditInlineMessageText(
|
|
||||||
inlineMessageId,
|
|
||||||
text,
|
|
||||||
parseMode,
|
|
||||||
null,
|
|
||||||
disableWebPagePreview,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun EditInlineMessageText(
|
|
||||||
inlineMessageId: InlineMessageIdentifier,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
disableWebPagePreview: Boolean? = null,
|
|
||||||
replyMarkup: InlineKeyboardMarkup? = null
|
|
||||||
) = EditInlineMessageText(
|
|
||||||
inlineMessageId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
disableWebPagePreview,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class EditInlineMessageText internal constructor(
|
data class EditInlineMessageText(
|
||||||
@SerialName(inlineMessageIdField)
|
@SerialName(inlineMessageIdField)
|
||||||
override val inlineMessageId: InlineMessageIdentifier,
|
override val inlineMessageId: InlineMessageIdentifier,
|
||||||
@SerialName(textField)
|
@SerialName(textField)
|
||||||
override val text: String,
|
override val text: String,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(entitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(disableWebPagePreviewField)
|
@SerialName(disableWebPagePreviewField)
|
||||||
override val disableWebPagePreview: Boolean? = null,
|
override val disableWebPagePreview: Boolean? = null,
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
|
) : EditInlineMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage {
|
||||||
override val textSources: TextSourcesList? by lazy {
|
override fun method(): String = editMessageMediaMethod
|
||||||
rawEntities ?.asTextSources(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = editMessageTextMethod
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package dev.inmo.tgbotapi.requests.games.abstracts
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||||
import dev.inmo.tgbotapi.types.UserId
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
import dev.inmo.tgbotapi.types.games.GameHighScore
|
import dev.inmo.tgbotapi.types.games.GameHighScore
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
@@ -16,5 +15,4 @@ interface GetGameHighScores : SimpleRequest<List<GameHighScore>> {
|
|||||||
get() = GameHighScoresSerializer
|
get() = GameHighScoresSerializer
|
||||||
}
|
}
|
||||||
|
|
||||||
@RiskFeature
|
internal object GameHighScoresSerializer : KSerializer<List<GameHighScore>> by ListSerializer(GameHighScore.serializer())
|
||||||
object GameHighScoresSerializer : KSerializer<List<GameHighScore>> by ListSerializer(GameHighScore.serializer())
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.local
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import kotlinx.serialization.builtins.serializer
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to close the bot instance before moving it from one local server to another. You need to delete the
|
|
||||||
* webhook before calling this method to ensure that the bot isn't launched again after server restart. The method will
|
|
||||||
* return error 429 in the first 10 minutes after the bot is launched.
|
|
||||||
*
|
|
||||||
* @see io.ktor.client.features.ClientRequestException
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
object Close : SimpleRequest<Boolean> {
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
|
|
||||||
override fun method(): String = "close"
|
|
||||||
|
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
|
||||||
get() = Boolean.serializer()
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.local
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import kotlinx.serialization.builtins.serializer
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to log out from the cloud Bot API server before launching the bot locally. You **must** log out the bot
|
|
||||||
* before running it locally, otherwise there is no guarantee that the bot will receive updates. After a successful
|
|
||||||
* call, you will not be able to log in again using the same token for 10 minutes
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
object LogOut : SimpleRequest<Boolean> {
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
|
|
||||||
override fun method(): String = "logOut"
|
|
||||||
|
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
|
||||||
get() = Boolean.serializer()
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.requests.send
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.types.MessageAction
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
|
||||||
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
|
||||||
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.utils.extensions.makeString
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
|
|
||||||
fun CopyMessage(
|
|
||||||
fromChatId: ChatIdentifier,
|
|
||||||
toChatId: ChatIdentifier,
|
|
||||||
messageId: MessageIdentifier,
|
|
||||||
text: String? = null,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = CopyMessage(fromChatId, toChatId, messageId, text, parseMode, null, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
|
||||||
|
|
||||||
fun CopyMessage(
|
|
||||||
fromChatId: ChatIdentifier,
|
|
||||||
toChatId: ChatIdentifier,
|
|
||||||
messageId: MessageIdentifier,
|
|
||||||
entities: List<TextSource>,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = CopyMessage(
|
|
||||||
fromChatId,
|
|
||||||
toChatId,
|
|
||||||
messageId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class CopyMessage internal constructor(
|
|
||||||
@SerialName(fromChatIdField)
|
|
||||||
val fromChatId: ChatIdentifier,
|
|
||||||
@SerialName(chatIdField)
|
|
||||||
val toChatId: ChatIdentifier,
|
|
||||||
@SerialName(messageIdField)
|
|
||||||
override val messageId: MessageIdentifier,
|
|
||||||
@SerialName(captionField)
|
|
||||||
override val text: String? = null,
|
|
||||||
@SerialName(parseModeField)
|
|
||||||
override val parseMode: ParseMode? = null,
|
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(disableNotificationField)
|
|
||||||
override val disableNotification: Boolean = false,
|
|
||||||
@SerialName(replyToMessageIdField)
|
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
|
||||||
): SimpleRequest<MessageIdentifier>,
|
|
||||||
ReplyingMarkupSendMessageRequest<MessageIdentifier>,
|
|
||||||
MessageAction,
|
|
||||||
TextedOutput {
|
|
||||||
override val chatId: ChatIdentifier
|
|
||||||
get() = fromChatId
|
|
||||||
override val textSources: List<TextSource>? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = "copyMessage"
|
|
||||||
|
|
||||||
override val resultDeserializer: DeserializationStrategy<MessageIdentifier>
|
|
||||||
get() = MessageIdSerializer
|
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
|
||||||
get() = serializer()
|
|
||||||
}
|
|
||||||
@@ -26,8 +26,6 @@ data class SendContact(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendMessageRequest<ContentMessage<ContactContent>>,
|
) : SendMessageRequest<ContentMessage<ContactContent>>,
|
||||||
@@ -38,7 +36,6 @@ data class SendContact(
|
|||||||
contact: Contact,
|
contact: Contact,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): this(
|
): this(
|
||||||
chatId,
|
chatId,
|
||||||
@@ -47,7 +44,6 @@ data class SendContact(
|
|||||||
contact.lastName,
|
contact.lastName,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,13 +58,11 @@ fun Contact.toRequest(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): SendContact = SendContact(
|
): SendContact = SendContact(
|
||||||
chatId,
|
chatId,
|
||||||
this,
|
this,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ data class SendDice(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : ReplyingMarkupSendMessageRequest<ContentMessage<DiceContent>>, ReplyMessageId, DisableNotification {
|
) : ReplyingMarkupSendMessageRequest<ContentMessage<DiceContent>>, ReplyMessageId, DisableNotification {
|
||||||
|
|||||||
@@ -1,79 +1,19 @@
|
|||||||
package dev.inmo.tgbotapi.requests.send
|
package dev.inmo.tgbotapi.requests.send
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
|
||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.LocationContent
|
import dev.inmo.tgbotapi.types.message.content.LocationContent
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
|
||||||
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
||||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
= TelegramBotAPIMessageDeserializationStrategyClass()
|
||||||
|
|
||||||
fun SendLocation(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
latitude: Double,
|
|
||||||
longitude: Double,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendLocation(
|
|
||||||
chatId,
|
|
||||||
latitude,
|
|
||||||
longitude,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun SendStaticLocation(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
latitude: Double,
|
|
||||||
longitude: Double,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendLocation(chatId, latitude, longitude, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
|
||||||
|
|
||||||
fun SendLiveLocation(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
latitude: Double,
|
|
||||||
longitude: Double,
|
|
||||||
livePeriod: Seconds,
|
|
||||||
horizontalAccuracy: Meters? = null,
|
|
||||||
heading: Degrees? = null,
|
|
||||||
proximityAlertRadius: Meters? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendLocation(
|
|
||||||
chatId,
|
|
||||||
latitude,
|
|
||||||
longitude,
|
|
||||||
livePeriod,
|
|
||||||
horizontalAccuracy,
|
|
||||||
heading,
|
|
||||||
proximityAlertRadius,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SendLocation internal constructor(
|
data class SendLocation(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(latitudeField)
|
@SerialName(latitudeField)
|
||||||
@@ -81,28 +21,16 @@ data class SendLocation internal constructor(
|
|||||||
@SerialName(longitudeField)
|
@SerialName(longitudeField)
|
||||||
override val longitude: Double,
|
override val longitude: Double,
|
||||||
@SerialName(livePeriodField)
|
@SerialName(livePeriodField)
|
||||||
override val livePeriod: Seconds? = null,
|
val livePeriod: Long? = null,
|
||||||
@SerialName(horizontalAccuracyField)
|
|
||||||
override val horizontalAccuracy: Meters? = null,
|
|
||||||
@SerialName(headingField)
|
|
||||||
override val heading: Degrees? = null,
|
|
||||||
@SerialName(proximityAlertRadiusField)
|
|
||||||
override val proximityAlertRadius: Meters? = null,
|
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendMessageRequest<ContentMessage<LocationContent>>,
|
) : SendMessageRequest<ContentMessage<LocationContent>>,
|
||||||
ReplyingMarkupSendMessageRequest<ContentMessage<LocationContent>>,
|
ReplyingMarkupSendMessageRequest<ContentMessage<LocationContent>>,
|
||||||
PositionedSendMessageRequest<ContentMessage<LocationContent>>,
|
PositionedSendMessageRequest<ContentMessage<LocationContent>>
|
||||||
HorizontallyAccured,
|
|
||||||
Livable,
|
|
||||||
ProximityAlertable,
|
|
||||||
Headed
|
|
||||||
{
|
{
|
||||||
override fun method(): String = "sendLocation"
|
override fun method(): String = "sendLocation"
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
|
||||||
@@ -114,8 +42,5 @@ data class SendLocation internal constructor(
|
|||||||
if (livePeriod != null && livePeriod !in livePeriodLimit) {
|
if (livePeriod != null && livePeriod !in livePeriodLimit) {
|
||||||
error("Live period for sending location must be in $livePeriodLimit, but was $livePeriod")
|
error("Live period for sending location must be in $livePeriodLimit, but was $livePeriod")
|
||||||
}
|
}
|
||||||
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
|
|
||||||
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,80 +3,32 @@ package dev.inmo.tgbotapi.requests.send
|
|||||||
import dev.inmo.tgbotapi.CommonAbstracts.types.DisableWebPagePreview
|
import dev.inmo.tgbotapi.CommonAbstracts.types.DisableWebPagePreview
|
||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
internal val TextContentMessageResultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>
|
internal val TextContentMessageResultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>
|
||||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
= TelegramBotAPIMessageDeserializationStrategyClass()
|
||||||
|
|
||||||
fun SendTextMessage(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
text: String,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
disableWebPagePreview: Boolean? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendTextMessage(
|
|
||||||
chatId,
|
|
||||||
text,
|
|
||||||
parseMode,
|
|
||||||
null,
|
|
||||||
disableWebPagePreview,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun SendTextMessage(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
disableWebPagePreview: Boolean? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendTextMessage(
|
|
||||||
chatId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
disableWebPagePreview,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SendTextMessage internal constructor(
|
data class SendTextMessage(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(textField)
|
@SerialName(textField)
|
||||||
override val text: String,
|
override val text: String,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(entitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(disableWebPagePreviewField)
|
@SerialName(disableWebPagePreviewField)
|
||||||
override val disableWebPagePreview: Boolean? = null,
|
override val disableWebPagePreview: Boolean? = null,
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendMessageRequest<ContentMessage<TextContent>>,
|
) : SendMessageRequest<ContentMessage<TextContent>>,
|
||||||
@@ -84,10 +36,6 @@ data class SendTextMessage internal constructor(
|
|||||||
TextableSendMessageRequest<ContentMessage<TextContent>>,
|
TextableSendMessageRequest<ContentMessage<TextContent>>,
|
||||||
DisableWebPagePreview
|
DisableWebPagePreview
|
||||||
{
|
{
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (text.length !in textLength) {
|
if (text.length !in textLength) {
|
||||||
throwRangeError("Text length", textLength, text.length)
|
throwRangeError("Text length", textLength, text.length)
|
||||||
|
|||||||
@@ -25,19 +25,11 @@ data class SendVenue(
|
|||||||
@SerialName(addressField)
|
@SerialName(addressField)
|
||||||
val address: String,
|
val address: String,
|
||||||
@SerialName(foursquareIdField)
|
@SerialName(foursquareIdField)
|
||||||
val foursquareId: FoursquareId? = null,
|
val foursquareId: String? = null,
|
||||||
@SerialName(foursquareTypeField)
|
|
||||||
val foursquareType: FoursquareType? = null,
|
|
||||||
@SerialName(googlePlaceIdField)
|
|
||||||
val googlePlaceId: GooglePlaceId? = null,
|
|
||||||
@SerialName(googlePlaceTypeField)
|
|
||||||
val googlePlaceType: GooglePlaceType? = null,
|
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendMessageRequest<ContentMessage<VenueContent>>,
|
) : SendMessageRequest<ContentMessage<VenueContent>>,
|
||||||
@@ -50,22 +42,17 @@ data class SendVenue(
|
|||||||
venue: Venue,
|
venue: Venue,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): this(
|
): this(
|
||||||
chatId = chatId,
|
chatId,
|
||||||
latitude = venue.location.latitude,
|
venue.location.latitude,
|
||||||
longitude = venue.location.longitude,
|
venue.location.longitude,
|
||||||
title = venue.title,
|
venue.title,
|
||||||
address = venue.address,
|
venue.address,
|
||||||
foursquareId = venue.foursquareId,
|
venue.foursquareId,
|
||||||
foursquareType = venue.foursquareType,
|
disableNotification,
|
||||||
googlePlaceId = venue.googlePlaceId,
|
replyToMessageId,
|
||||||
googlePlaceType = venue.googlePlaceType,
|
replyMarkup
|
||||||
disableNotification = disableNotification,
|
|
||||||
replyToMessageId = replyToMessageId,
|
|
||||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
|
||||||
replyMarkup = replyMarkup
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun method(): String = "sendVenue"
|
override fun method(): String = "sendVenue"
|
||||||
@@ -79,13 +66,11 @@ fun Venue.toRequest(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): SendVenue = SendVenue(
|
): SendVenue = SendVenue(
|
||||||
chatId,
|
chatId,
|
||||||
this,
|
this,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.requests.send.abstracts
|
package dev.inmo.tgbotapi.requests.send.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
|
interface PositionedSendMessageRequest<T: Any>: SendMessageRequest<T> {
|
||||||
|
val latitude: Double
|
||||||
interface PositionedSendMessageRequest<T: Any>: SendMessageRequest<T>, Locationed
|
val longitude: Double
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.requests.send.abstracts
|
package dev.inmo.tgbotapi.requests.send.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
|
|
||||||
interface TextableSendMessageRequest<T: Any>: SendMessageRequest<T>, TextedOutput
|
interface TextableSendMessageRequest<T: Any>: SendMessageRequest<T> {
|
||||||
|
val text: String?
|
||||||
|
val parseMode: ParseMode?
|
||||||
|
}
|
||||||
@@ -22,8 +22,6 @@ data class SendGame (
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendMessageRequest<ContentMessage<GameContent>>,
|
) : SendMessageRequest<ContentMessage<GameContent>>,
|
||||||
|
|||||||
@@ -4,15 +4,12 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.AnimationContent
|
import dev.inmo.tgbotapi.types.message.content.media.AnimationContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
@@ -21,14 +18,13 @@ fun SendAnimation(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
animation: InputFile,
|
animation: InputFile,
|
||||||
thumb: InputFile? = null,
|
thumb: InputFile? = null,
|
||||||
text: String? = null,
|
caption: String? = null,
|
||||||
parseMode: ParseMode? = null,
|
parseMode: ParseMode? = null,
|
||||||
duration: Long? = null,
|
duration: Long? = null,
|
||||||
width: Int? = null,
|
width: Int? = null,
|
||||||
height: Int? = null,
|
height: Int? = null,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<AnimationContent>> {
|
): Request<ContentMessage<AnimationContent>> {
|
||||||
val animationAsFileId = (animation as? FileId) ?.fileId
|
val animationAsFileId = (animation as? FileId) ?.fileId
|
||||||
@@ -40,59 +36,13 @@ fun SendAnimation(
|
|||||||
chatId,
|
chatId,
|
||||||
animationAsFileId,
|
animationAsFileId,
|
||||||
thumbAsFileId,
|
thumbAsFileId,
|
||||||
text,
|
caption,
|
||||||
parseMode,
|
parseMode,
|
||||||
null,
|
|
||||||
duration,
|
duration,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
return if (animationAsFile == null && thumbAsFile == null) {
|
|
||||||
data
|
|
||||||
} else {
|
|
||||||
MultipartRequestImpl(
|
|
||||||
data,
|
|
||||||
SendAnimationFiles(animationAsFile, thumbAsFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SendAnimation(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
animation: InputFile,
|
|
||||||
thumb: InputFile? = null,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
duration: Long? = null,
|
|
||||||
width: Int? = null,
|
|
||||||
height: Int? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
): Request<ContentMessage<AnimationContent>> {
|
|
||||||
val animationAsFileId = (animation as? FileId) ?.fileId
|
|
||||||
val animationAsFile = animation as? MultipartFile
|
|
||||||
val thumbAsFileId = (thumb as? FileId) ?.fileId
|
|
||||||
val thumbAsFile = thumb as? MultipartFile
|
|
||||||
|
|
||||||
val data = SendAnimationData(
|
|
||||||
chatId,
|
|
||||||
animationAsFileId,
|
|
||||||
thumbAsFileId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
duration,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -121,8 +71,6 @@ data class SendAnimationData internal constructor(
|
|||||||
override val text: String? = null,
|
override val text: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(durationField)
|
@SerialName(durationField)
|
||||||
override val duration: Long? = null,
|
override val duration: Long? = null,
|
||||||
@SerialName(widthField)
|
@SerialName(widthField)
|
||||||
@@ -133,8 +81,6 @@ data class SendAnimationData internal constructor(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : DataRequest<ContentMessage<AnimationContent>>,
|
) : DataRequest<ContentMessage<AnimationContent>>,
|
||||||
@@ -145,10 +91,6 @@ data class SendAnimationData internal constructor(
|
|||||||
DuratedSendMessageRequest<ContentMessage<AnimationContent>>,
|
DuratedSendMessageRequest<ContentMessage<AnimationContent>>,
|
||||||
SizedSendMessageRequest<ContentMessage<AnimationContent>>
|
SizedSendMessageRequest<ContentMessage<AnimationContent>>
|
||||||
{
|
{
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text ?.let {
|
text ?.let {
|
||||||
if (it.length !in captionLength) {
|
if (it.length !in captionLength) {
|
||||||
|
|||||||
@@ -5,15 +5,12 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
@@ -22,14 +19,13 @@ fun SendAudio(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
audio: InputFile,
|
audio: InputFile,
|
||||||
thumb: InputFile? = null,
|
thumb: InputFile? = null,
|
||||||
text: String? = null,
|
caption: String? = null,
|
||||||
parseMode: ParseMode? = null,
|
parseMode: ParseMode? = null,
|
||||||
duration: Long? = null,
|
duration: Long? = null,
|
||||||
performer: String? = null,
|
performer: String? = null,
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<AudioContent>> {
|
): Request<ContentMessage<AudioContent>> {
|
||||||
val audioAsFileId = (audio as? FileId) ?.fileId
|
val audioAsFileId = (audio as? FileId) ?.fileId
|
||||||
@@ -41,59 +37,13 @@ fun SendAudio(
|
|||||||
chatId,
|
chatId,
|
||||||
audioAsFileId,
|
audioAsFileId,
|
||||||
thumbAsFileId,
|
thumbAsFileId,
|
||||||
text,
|
caption,
|
||||||
parseMode,
|
parseMode,
|
||||||
null,
|
|
||||||
duration,
|
duration,
|
||||||
performer,
|
performer,
|
||||||
title,
|
title,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
return if (audioAsFile == null && thumbAsFile == null) {
|
|
||||||
data
|
|
||||||
} else {
|
|
||||||
MultipartRequestImpl(
|
|
||||||
data,
|
|
||||||
SendAudioFiles(audioAsFile, thumbAsFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SendAudio(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
audio: InputFile,
|
|
||||||
thumb: InputFile? = null,
|
|
||||||
entities: List<TextSource>,
|
|
||||||
duration: Long? = null,
|
|
||||||
performer: String? = null,
|
|
||||||
title: String? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
): Request<ContentMessage<AudioContent>> {
|
|
||||||
val audioAsFileId = (audio as? FileId) ?.fileId
|
|
||||||
val audioAsFile = audio as? MultipartFile
|
|
||||||
val thumbAsFileId = (thumb as? FileId) ?.fileId
|
|
||||||
val thumbAsFile = thumb as? MultipartFile
|
|
||||||
|
|
||||||
val data = SendAudioData(
|
|
||||||
chatId,
|
|
||||||
audioAsFileId,
|
|
||||||
thumbAsFileId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
duration,
|
|
||||||
performer,
|
|
||||||
title,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -122,8 +72,6 @@ data class SendAudioData internal constructor(
|
|||||||
override val text: String? = null,
|
override val text: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(durationField)
|
@SerialName(durationField)
|
||||||
override val duration: Long? = null,
|
override val duration: Long? = null,
|
||||||
@SerialName(performerField)
|
@SerialName(performerField)
|
||||||
@@ -134,8 +82,6 @@ data class SendAudioData internal constructor(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : DataRequest<ContentMessage<AudioContent>>,
|
) : DataRequest<ContentMessage<AudioContent>>,
|
||||||
@@ -147,10 +93,6 @@ data class SendAudioData internal constructor(
|
|||||||
DuratedSendMessageRequest<ContentMessage<AudioContent>>,
|
DuratedSendMessageRequest<ContentMessage<AudioContent>>,
|
||||||
Performerable
|
Performerable
|
||||||
{
|
{
|
||||||
override val textSources: List<TextSource>? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text ?.let {
|
text ?.let {
|
||||||
if (it.length !in captionLength) {
|
if (it.length !in captionLength) {
|
||||||
|
|||||||
@@ -4,39 +4,25 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to send general files. On success, the sent [ContentMessage] with [DocumentContent] is returned.
|
|
||||||
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
|
|
||||||
*
|
|
||||||
* @param disableContentTypeDetection Disables automatic server-side content type detection for [document] [MultipartFile]
|
|
||||||
*
|
|
||||||
* @see ContentMessage
|
|
||||||
* @see DocumentContent
|
|
||||||
*/
|
|
||||||
fun SendDocument(
|
fun SendDocument(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
document: InputFile,
|
document: InputFile,
|
||||||
thumb: InputFile? = null,
|
thumb: InputFile? = null,
|
||||||
text: String? = null,
|
caption: String? = null,
|
||||||
parseMode: ParseMode? = null,
|
parseMode: ParseMode? = null,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
replyMarkup: KeyboardMarkup? = null
|
||||||
replyMarkup: KeyboardMarkup? = null,
|
|
||||||
disableContentTypeDetection: Boolean? = null
|
|
||||||
): Request<ContentMessage<DocumentContent>> {
|
): Request<ContentMessage<DocumentContent>> {
|
||||||
val documentAsFileId = (document as? FileId) ?.fileId
|
val documentAsFileId = (document as? FileId) ?.fileId
|
||||||
val documentAsFile = document as? MultipartFile
|
val documentAsFile = document as? MultipartFile
|
||||||
@@ -47,63 +33,11 @@ fun SendDocument(
|
|||||||
chatId,
|
chatId,
|
||||||
documentAsFileId,
|
documentAsFileId,
|
||||||
thumbAsFileId,
|
thumbAsFileId,
|
||||||
text,
|
caption,
|
||||||
parseMode,
|
parseMode,
|
||||||
null,
|
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
replyMarkup
|
||||||
replyMarkup,
|
|
||||||
disableContentTypeDetection
|
|
||||||
)
|
|
||||||
|
|
||||||
return if (documentAsFile == null && thumbAsFile == null) {
|
|
||||||
data
|
|
||||||
} else {
|
|
||||||
MultipartRequestImpl(
|
|
||||||
data,
|
|
||||||
SendDocumentFiles(documentAsFile, thumbAsFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to send general files. On success, the sent [ContentMessage] with [DocumentContent] is returned.
|
|
||||||
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
|
|
||||||
*
|
|
||||||
* @param disableContentTypeDetection Disables automatic server-side content type detection for [document] [MultipartFile]
|
|
||||||
*
|
|
||||||
* @see ContentMessage
|
|
||||||
* @see DocumentContent
|
|
||||||
*/
|
|
||||||
fun SendDocument(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
document: InputFile,
|
|
||||||
thumb: InputFile? = null,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null,
|
|
||||||
disableContentTypeDetection: Boolean? = null
|
|
||||||
): Request<ContentMessage<DocumentContent>> {
|
|
||||||
val documentAsFileId = (document as? FileId) ?.fileId
|
|
||||||
val documentAsFile = document as? MultipartFile
|
|
||||||
val thumbAsFileId = (thumb as? FileId) ?.fileId
|
|
||||||
val thumbAsFile = thumb as? MultipartFile
|
|
||||||
|
|
||||||
val data = SendDocumentData(
|
|
||||||
chatId,
|
|
||||||
documentAsFileId,
|
|
||||||
thumbAsFileId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup,
|
|
||||||
disableContentTypeDetection
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return if (documentAsFile == null && thumbAsFile == null) {
|
return if (documentAsFile == null && thumbAsFile == null) {
|
||||||
@@ -119,15 +53,6 @@ fun SendDocument(
|
|||||||
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<DocumentContent>>
|
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<DocumentContent>>
|
||||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
= TelegramBotAPIMessageDeserializationStrategyClass()
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to send general files. On success, the sent [ContentMessage] with [DocumentContent] is returned.
|
|
||||||
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
|
|
||||||
*
|
|
||||||
* @param disableContentTypeDetection Disables automatic server-side content type detection for [document] [MultipartFile]
|
|
||||||
*
|
|
||||||
* @see ContentMessage
|
|
||||||
* @see DocumentContent
|
|
||||||
*/
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SendDocumentData internal constructor(
|
data class SendDocumentData internal constructor(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
@@ -140,28 +65,18 @@ data class SendDocumentData internal constructor(
|
|||||||
override val text: String? = null,
|
override val text: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null,
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
@SerialName(disableContentTypeDetectionField)
|
|
||||||
val disableContentTypeDetection: Boolean? = null
|
|
||||||
) : DataRequest<ContentMessage<DocumentContent>>,
|
) : DataRequest<ContentMessage<DocumentContent>>,
|
||||||
SendMessageRequest<ContentMessage<DocumentContent>>,
|
SendMessageRequest<ContentMessage<DocumentContent>>,
|
||||||
ReplyingMarkupSendMessageRequest<ContentMessage<DocumentContent>>,
|
ReplyingMarkupSendMessageRequest<ContentMessage<DocumentContent>>,
|
||||||
TextableSendMessageRequest<ContentMessage<DocumentContent>>,
|
TextableSendMessageRequest<ContentMessage<DocumentContent>>,
|
||||||
ThumbedSendMessageRequest<ContentMessage<DocumentContent>>
|
ThumbedSendMessageRequest<ContentMessage<DocumentContent>>
|
||||||
{
|
{
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text ?.let {
|
text ?.let {
|
||||||
if (it.length !in captionLength) {
|
if (it.length !in captionLength) {
|
||||||
|
|||||||
@@ -8,26 +8,18 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
import dev.inmo.tgbotapi.utils.toJsonWithoutNulls
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
|
|
||||||
import dev.inmo.tgbotapi.utils.*
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.json.buildJsonArray
|
import kotlinx.serialization.json.buildJsonArray
|
||||||
|
|
||||||
const val rawSendingMediaGroupsWarning = "Media groups contains restrictions related to combinations of media" +
|
fun SendMediaGroup(
|
||||||
" types. Currently it is possible to combine photo + video OR audio OR documents"
|
|
||||||
|
|
||||||
@RiskFeature(rawSendingMediaGroupsWarning)
|
|
||||||
fun <T : MediaGroupContent> SendMediaGroup(
|
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
media: List<MediaGroupMemberInputMedia>,
|
media: List<MediaGroupMemberInputMedia>,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null
|
||||||
allowSendingWithoutReply: Boolean? = null
|
): Request<List<MediaGroupMessage>> {
|
||||||
): Request<List<MediaGroupMessage<T>>> {
|
|
||||||
if (media.size !in mediaCountInMediaGroup) {
|
if (media.size !in mediaCountInMediaGroup) {
|
||||||
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
|
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
|
||||||
}
|
}
|
||||||
@@ -47,64 +39,20 @@ fun <T : MediaGroupContent> SendMediaGroup(
|
|||||||
chatId,
|
chatId,
|
||||||
media,
|
media,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId
|
||||||
allowSendingWithoutReply
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return (if (files.isEmpty()) {
|
return if (files.isEmpty()) {
|
||||||
data
|
data
|
||||||
} else {
|
} else {
|
||||||
MultipartRequestImpl(
|
MultipartRequestImpl(
|
||||||
data,
|
data,
|
||||||
SendMediaGroupFiles(files)
|
SendMediaGroupFiles(files)
|
||||||
)
|
)
|
||||||
}) as Request<List<MediaGroupMessage<T>>>
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private val messagesListSerializer: KSerializer<List<MediaGroupMessage>>
|
||||||
* Use this method to be sure that you are correctly sending playlist with audios
|
|
||||||
*
|
|
||||||
* @see InputMediaAudio
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
inline fun SendPlaylist(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
media: List<AudioMediaGroupMemberInputMedia>,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null
|
|
||||||
) = SendMediaGroup<AudioContent>(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to be sure that you are correctly sending documents media group
|
|
||||||
*
|
|
||||||
* @see InputMediaDocument
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
inline fun SendDocumentsGroup(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
media: List<DocumentMediaGroupMemberInputMedia>,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null
|
|
||||||
) = SendMediaGroup<DocumentContent>(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to be sure that you are correctly sending visual media group
|
|
||||||
*
|
|
||||||
* @see InputMediaPhoto
|
|
||||||
* @see InputMediaVideo
|
|
||||||
*/
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
inline fun SendVisualMediaGroup(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
media: List<VisualMediaGroupMemberInputMedia>,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null
|
|
||||||
) = SendMediaGroup<VisualMediaGroupContent>(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
|
|
||||||
|
|
||||||
private val messagesListSerializer: KSerializer<List<MediaGroupMessage<MediaGroupContent>>>
|
|
||||||
= ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass())
|
= ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass())
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -115,10 +63,8 @@ data class SendMediaGroupData internal constructor(
|
|||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
) : DataRequest<List<MediaGroupMessage>>, SendMessageRequest<List<MediaGroupMessage>> {
|
||||||
override val allowSendingWithoutReply: Boolean? = null
|
|
||||||
) : DataRequest<List<MediaGroupMessage<MediaGroupContent>>>, SendMessageRequest<List<MediaGroupMessage<MediaGroupContent>>> {
|
|
||||||
@SerialName(mediaField)
|
@SerialName(mediaField)
|
||||||
private val convertedMedia: String
|
private val convertedMedia: String
|
||||||
get() = buildJsonArray {
|
get() = buildJsonArray {
|
||||||
@@ -131,7 +77,7 @@ data class SendMediaGroupData internal constructor(
|
|||||||
override fun method(): String = "sendMediaGroup"
|
override fun method(): String = "sendMediaGroup"
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
override val resultDeserializer: DeserializationStrategy<List<MediaGroupMessage<MediaGroupContent>>>
|
override val resultDeserializer: DeserializationStrategy<List<MediaGroupMessage>>
|
||||||
get() = messagesListSerializer
|
get() = messagesListSerializer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,65 +4,31 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
|
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
fun SendPhoto(
|
fun SendPhoto(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
photo: InputFile,
|
photo: InputFile,
|
||||||
text: String? = null,
|
caption: String? = null,
|
||||||
parseMode: ParseMode? = null,
|
parseMode: ParseMode? = null,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<PhotoContent>> {
|
): Request<ContentMessage<PhotoContent>> {
|
||||||
val data = SendPhotoData(
|
val data = SendPhotoData(
|
||||||
chatId,
|
chatId,
|
||||||
(photo as? FileId) ?.fileId,
|
(photo as? FileId) ?.fileId,
|
||||||
text,
|
caption,
|
||||||
parseMode,
|
parseMode,
|
||||||
null,
|
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
return data.photo ?.let {
|
|
||||||
data
|
|
||||||
} ?: MultipartRequestImpl(
|
|
||||||
data,
|
|
||||||
SendPhotoFiles(photo as MultipartFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SendPhoto(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
photo: InputFile,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
): Request<ContentMessage<PhotoContent>> {
|
|
||||||
val data = SendPhotoData(
|
|
||||||
chatId,
|
|
||||||
(photo as? FileId)?.fileId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
return data.photo ?.let {
|
return data.photo ?.let {
|
||||||
@@ -86,14 +52,10 @@ data class SendPhotoData internal constructor(
|
|||||||
override val text: String? = null,
|
override val text: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : DataRequest<ContentMessage<PhotoContent>>,
|
) : DataRequest<ContentMessage<PhotoContent>>,
|
||||||
@@ -101,10 +63,6 @@ data class SendPhotoData internal constructor(
|
|||||||
ReplyingMarkupSendMessageRequest<ContentMessage<PhotoContent>>,
|
ReplyingMarkupSendMessageRequest<ContentMessage<PhotoContent>>,
|
||||||
TextableSendMessageRequest<ContentMessage<PhotoContent>>
|
TextableSendMessageRequest<ContentMessage<PhotoContent>>
|
||||||
{
|
{
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text ?.let {
|
text ?.let {
|
||||||
if (it.length !in captionLength) {
|
if (it.length !in captionLength) {
|
||||||
|
|||||||
@@ -17,14 +17,12 @@ fun SendSticker(
|
|||||||
sticker: InputFile,
|
sticker: InputFile,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<StickerContent>> = SendStickerByFileId(
|
): Request<ContentMessage<StickerContent>> = SendStickerByFileId(
|
||||||
chatId,
|
chatId,
|
||||||
sticker as? FileId,
|
sticker as? FileId,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
).let {
|
).let {
|
||||||
when (sticker) {
|
when (sticker) {
|
||||||
@@ -46,8 +44,6 @@ data class SendStickerByFileId internal constructor(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendMessageRequest<ContentMessage<StickerContent>>, ReplyingMarkupSendMessageRequest<ContentMessage<StickerContent>> {
|
) : SendMessageRequest<ContentMessage<StickerContent>>, ReplyingMarkupSendMessageRequest<ContentMessage<StickerContent>> {
|
||||||
|
|||||||
@@ -4,15 +4,12 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
|
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
@@ -21,7 +18,7 @@ fun SendVideo(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
video: InputFile,
|
video: InputFile,
|
||||||
thumb: InputFile? = null,
|
thumb: InputFile? = null,
|
||||||
text: String? = null,
|
caption: String? = null,
|
||||||
parseMode: ParseMode? = null,
|
parseMode: ParseMode? = null,
|
||||||
duration: Long? = null,
|
duration: Long? = null,
|
||||||
width: Int? = null,
|
width: Int? = null,
|
||||||
@@ -29,7 +26,6 @@ fun SendVideo(
|
|||||||
supportStreaming: Boolean? = null,
|
supportStreaming: Boolean? = null,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<VideoContent>> {
|
): Request<ContentMessage<VideoContent>> {
|
||||||
val videoAsFileId = (video as? FileId) ?.fileId
|
val videoAsFileId = (video as? FileId) ?.fileId
|
||||||
@@ -41,62 +37,14 @@ fun SendVideo(
|
|||||||
chatId,
|
chatId,
|
||||||
videoAsFileId,
|
videoAsFileId,
|
||||||
thumbAsFileId,
|
thumbAsFileId,
|
||||||
text,
|
caption,
|
||||||
parseMode,
|
parseMode,
|
||||||
null,
|
|
||||||
duration,
|
duration,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
supportStreaming,
|
supportStreaming,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
return if (videoAsFile == null && thumbAsFile == null) {
|
|
||||||
data
|
|
||||||
} else {
|
|
||||||
MultipartRequestImpl(
|
|
||||||
data,
|
|
||||||
SendVideoFiles(videoAsFile, thumbAsFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SendVideo(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
video: InputFile,
|
|
||||||
thumb: InputFile? = null,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
duration: Long? = null,
|
|
||||||
width: Int? = null,
|
|
||||||
height: Int? = null,
|
|
||||||
supportStreaming: Boolean? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
): Request<ContentMessage<VideoContent>> {
|
|
||||||
val videoAsFileId = (video as? FileId) ?.fileId
|
|
||||||
val videoAsFile = video as? MultipartFile
|
|
||||||
val thumbAsFileId = (thumb as? FileId) ?.fileId
|
|
||||||
val thumbAsFile = thumb as? MultipartFile
|
|
||||||
|
|
||||||
val data = SendVideoData(
|
|
||||||
chatId,
|
|
||||||
videoAsFileId,
|
|
||||||
thumbAsFileId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
duration,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
supportStreaming,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -125,8 +73,6 @@ data class SendVideoData internal constructor(
|
|||||||
override val text: String? = null,
|
override val text: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(durationField)
|
@SerialName(durationField)
|
||||||
override val duration: Long? = null,
|
override val duration: Long? = null,
|
||||||
@SerialName(widthField)
|
@SerialName(widthField)
|
||||||
@@ -139,8 +85,6 @@ data class SendVideoData internal constructor(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : DataRequest<ContentMessage<VideoContent>>,
|
) : DataRequest<ContentMessage<VideoContent>>,
|
||||||
@@ -151,10 +95,6 @@ data class SendVideoData internal constructor(
|
|||||||
DuratedSendMessageRequest<ContentMessage<VideoContent>>,
|
DuratedSendMessageRequest<ContentMessage<VideoContent>>,
|
||||||
SizedSendMessageRequest<ContentMessage<VideoContent>>
|
SizedSendMessageRequest<ContentMessage<VideoContent>>
|
||||||
{
|
{
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text ?.let {
|
text ?.let {
|
||||||
if (it.length !in captionLength) {
|
if (it.length !in captionLength) {
|
||||||
|
|||||||
@@ -4,22 +4,26 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
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.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.VideoNoteContent
|
import dev.inmo.tgbotapi.types.message.content.media.VideoNoteContent
|
||||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||||
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
fun SendVideoNote(
|
fun SendVideoNote(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
videoNote: InputFile,
|
videoNote: InputFile,
|
||||||
thumb: InputFile? = null,
|
thumb: InputFile? = null,
|
||||||
|
caption: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
duration: Long? = null,
|
duration: Long? = null,
|
||||||
size: Int? = null, // in documentation - length (size of video side)
|
size: Int? = null, // in documentation - length (size of video side)
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<VideoNoteContent>> {
|
): Request<ContentMessage<VideoNoteContent>> {
|
||||||
val videoNoteAsFileId = (videoNote as? FileId) ?.fileId
|
val videoNoteAsFileId = (videoNote as? FileId) ?.fileId
|
||||||
@@ -31,11 +35,12 @@ fun SendVideoNote(
|
|||||||
chatId,
|
chatId,
|
||||||
videoNoteAsFileId,
|
videoNoteAsFileId,
|
||||||
thumbAsFileId,
|
thumbAsFileId,
|
||||||
|
caption,
|
||||||
|
parseMode,
|
||||||
duration,
|
duration,
|
||||||
size,
|
size,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,6 +65,10 @@ data class SendVideoNoteData internal constructor(
|
|||||||
val videoNote: String? = null,
|
val videoNote: String? = null,
|
||||||
@SerialName(thumbField)
|
@SerialName(thumbField)
|
||||||
override val thumb: String? = null,
|
override val thumb: String? = null,
|
||||||
|
@SerialName(captionField)
|
||||||
|
override val text: String? = null,
|
||||||
|
@SerialName(parseModeField)
|
||||||
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(durationField)
|
@SerialName(durationField)
|
||||||
override val duration: Long? = null,
|
override val duration: Long? = null,
|
||||||
@SerialName(lengthField)
|
@SerialName(lengthField)
|
||||||
@@ -68,13 +77,12 @@ data class SendVideoNoteData internal constructor(
|
|||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : DataRequest<ContentMessage<VideoNoteContent>>,
|
) : DataRequest<ContentMessage<VideoNoteContent>>,
|
||||||
SendMessageRequest<ContentMessage<VideoNoteContent>>,
|
SendMessageRequest<ContentMessage<VideoNoteContent>>,
|
||||||
ReplyingMarkupSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
ReplyingMarkupSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
||||||
|
TextableSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
||||||
ThumbedSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
ThumbedSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
||||||
DuratedSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
DuratedSendMessageRequest<ContentMessage<VideoNoteContent>>,
|
||||||
SizedSendMessageRequest<ContentMessage<VideoNoteContent>>
|
SizedSendMessageRequest<ContentMessage<VideoNoteContent>>
|
||||||
@@ -82,6 +90,14 @@ data class SendVideoNoteData internal constructor(
|
|||||||
override val height: Int?
|
override val height: Int?
|
||||||
get() = width
|
get() = width
|
||||||
|
|
||||||
|
init {
|
||||||
|
text ?.let {
|
||||||
|
if (it.length !in captionLength) {
|
||||||
|
throwRangeError("Caption length", captionLength, it.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun method(): String = "sendVideoNote"
|
override fun method(): String = "sendVideoNote"
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<VideoNoteContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<VideoNoteContent>>
|
||||||
get() = commonResultDeserializer
|
get() = commonResultDeserializer
|
||||||
|
|||||||
@@ -4,15 +4,12 @@ import dev.inmo.tgbotapi.requests.abstracts.*
|
|||||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.*
|
import dev.inmo.tgbotapi.requests.send.media.base.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.VoiceContent
|
import dev.inmo.tgbotapi.types.message.content.media.VoiceContent
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
|
||||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
@@ -20,12 +17,11 @@ import kotlinx.serialization.*
|
|||||||
fun SendVoice(
|
fun SendVoice(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
voice: InputFile,
|
voice: InputFile,
|
||||||
text: String? = null,
|
caption: String? = null,
|
||||||
parseMode: ParseMode? = null,
|
parseMode: ParseMode? = null,
|
||||||
duration: Long? = null,
|
duration: Long? = null,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
): Request<ContentMessage<VoiceContent>> {
|
): Request<ContentMessage<VoiceContent>> {
|
||||||
val voiceAsFileId = (voice as? FileId) ?.fileId
|
val voiceAsFileId = (voice as? FileId) ?.fileId
|
||||||
@@ -34,49 +30,11 @@ fun SendVoice(
|
|||||||
val data = SendVoiceData(
|
val data = SendVoiceData(
|
||||||
chatId,
|
chatId,
|
||||||
voiceAsFileId,
|
voiceAsFileId,
|
||||||
text,
|
caption,
|
||||||
parseMode,
|
parseMode,
|
||||||
null,
|
|
||||||
duration,
|
duration,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
return if (voiceAsFile == null) {
|
|
||||||
data
|
|
||||||
} else {
|
|
||||||
MultipartRequestImpl(
|
|
||||||
data,
|
|
||||||
SendVoiceFiles(voiceAsFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SendVoice(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
voice: InputFile,
|
|
||||||
entities: TextSourcesList,
|
|
||||||
duration: Long? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
): Request<ContentMessage<VoiceContent>> {
|
|
||||||
val voiceAsFileId = (voice as? FileId) ?.fileId
|
|
||||||
val voiceAsFile = voice as? MultipartFile
|
|
||||||
|
|
||||||
val data = SendVoiceData(
|
|
||||||
chatId,
|
|
||||||
voiceAsFileId,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
duration,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -103,16 +61,12 @@ data class SendVoiceData internal constructor(
|
|||||||
override val text: String? = null,
|
override val text: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(captionEntitiesField)
|
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
@SerialName(durationField)
|
@SerialName(durationField)
|
||||||
override val duration: Long? = null,
|
override val duration: Long? = null,
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : DataRequest<ContentMessage<VoiceContent>>,
|
) : DataRequest<ContentMessage<VoiceContent>>,
|
||||||
@@ -121,10 +75,6 @@ data class SendVoiceData internal constructor(
|
|||||||
TextableSendMessageRequest<ContentMessage<VoiceContent>>,
|
TextableSendMessageRequest<ContentMessage<VoiceContent>>,
|
||||||
DuratedSendMessageRequest<ContentMessage<VoiceContent>>
|
DuratedSendMessageRequest<ContentMessage<VoiceContent>>
|
||||||
{
|
{
|
||||||
override val textSources: TextSourcesList? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text ?.let {
|
text ?.let {
|
||||||
if (it.length !in captionLength) {
|
if (it.length !in captionLength) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package dev.inmo.tgbotapi.requests.send.payments
|
package dev.inmo.tgbotapi.requests.send.payments
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.CommonSendInvoiceData
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.types.*
|
import dev.inmo.tgbotapi.CommonAbstracts.types.*
|
||||||
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
|
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
@@ -10,7 +9,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializ
|
|||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
import dev.inmo.tgbotapi.types.payments.LabeledPrice
|
||||||
import dev.inmo.tgbotapi.types.payments.LabeledPricesSerializer
|
import dev.inmo.tgbotapi.types.payments.LabeledPricesSerializer
|
||||||
import dev.inmo.tgbotapi.types.payments.abstracts.Currency
|
import dev.inmo.tgbotapi.types.payments.abstracts.*
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
private val invoiceMessageSerializer: DeserializationStrategy<ContentMessage<InvoiceContent>>
|
private val invoiceMessageSerializer: DeserializationStrategy<ContentMessage<InvoiceContent>>
|
||||||
@@ -24,49 +23,44 @@ data class SendInvoice(
|
|||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatId,
|
override val chatId: ChatId,
|
||||||
@SerialName(titleField)
|
@SerialName(titleField)
|
||||||
override val title: String,
|
val title: String,
|
||||||
@SerialName(descriptionField)
|
@SerialName(descriptionField)
|
||||||
override val description: String,
|
val description: String,
|
||||||
@SerialName(payloadField)
|
@SerialName(payloadField)
|
||||||
override val payload: String,
|
val payload: String,
|
||||||
@SerialName(providerTokenField)
|
@SerialName(providerTokenField)
|
||||||
override val providerToken: String,
|
val providerToken: String,
|
||||||
|
@SerialName(startParameterField)
|
||||||
|
val startParameter: StartParameter,
|
||||||
@SerialName(currencyField)
|
@SerialName(currencyField)
|
||||||
override val currency: Currency,
|
override val currency: Currency,
|
||||||
@Serializable(LabeledPricesSerializer::class)
|
@Serializable(LabeledPricesSerializer::class)
|
||||||
@SerialName(pricesField)
|
@SerialName(pricesField)
|
||||||
override val prices: List<LabeledPrice>,
|
override val prices: List<LabeledPrice>,
|
||||||
@SerialName(maxTipAmountField)
|
|
||||||
override val maxTipAmount: Int? = null,
|
|
||||||
@SerialName(suggestedTipAmountsField)
|
|
||||||
override val suggestedTipAmounts: List<Int>? = null,
|
|
||||||
@SerialName(startParameterField)
|
|
||||||
val startParameter: StartParameter? = null,
|
|
||||||
@SerialName(providerDataField)
|
@SerialName(providerDataField)
|
||||||
override val providerData: String? = null,
|
val providerData: String? = null,
|
||||||
@SerialName(requireNameField)
|
@SerialName(requireNameField)
|
||||||
override val requireName: Boolean = false,
|
val requireName: Boolean = false,
|
||||||
@SerialName(requirePhoneNumberField)
|
@SerialName(requirePhoneNumberField)
|
||||||
override val requirePhoneNumber: Boolean = false,
|
val requirePhoneNumber: Boolean = false,
|
||||||
@SerialName(requireEmailField)
|
@SerialName(requireEmailField)
|
||||||
override val requireEmail: Boolean = false,
|
val requireEmail: Boolean = false,
|
||||||
@SerialName(requireShippingAddressField)
|
@SerialName(requireShippingAddressField)
|
||||||
override val requireShippingAddress: Boolean = false,
|
val requireShippingAddress: Boolean = false,
|
||||||
@SerialName(shouldSendPhoneNumberToProviderField)
|
@SerialName(shouldSendPhoneNumberToProviderField)
|
||||||
override val shouldSendPhoneNumberToProvider: Boolean = false,
|
val shouldSendPhoneNumberToProvider: Boolean = false,
|
||||||
@SerialName(shouldSendEmailToProviderField)
|
@SerialName(shouldSendEmailToProviderField)
|
||||||
override val shouldSendEmailToProvider: Boolean = false,
|
val shouldSendEmailToProvider: Boolean = false,
|
||||||
@SerialName(priceDependOnShipAddressField)
|
@SerialName(priceDependOnShipAddressField)
|
||||||
override val priceDependOnShipAddress: Boolean = false,
|
val priceDependOnShipAddress: Boolean = false,
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||||
) : CommonSendInvoiceData,
|
) : Currencied,
|
||||||
|
Priced,
|
||||||
ChatRequest,
|
ChatRequest,
|
||||||
DisableNotification,
|
DisableNotification,
|
||||||
ReplyMessageId,
|
ReplyMessageId,
|
||||||
@@ -79,35 +73,24 @@ data class SendInvoice(
|
|||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|
||||||
@SerialName(photoUrlField)
|
@SerialName(photoUrlField)
|
||||||
override var photoUrl: String? = null
|
var photoUrl: String? = null
|
||||||
private set
|
private set
|
||||||
@SerialName(photoSizeField)
|
@SerialName(photoSizeField)
|
||||||
override var photoSize: Long? = null
|
var photoSize: Long? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@SerialName(photoWidthField)
|
@SerialName(photoWidthField)
|
||||||
override var photoWidth: Int? = null
|
var photoWidth: Int? = null
|
||||||
private set
|
private set
|
||||||
@SerialName(photoHeightField)
|
@SerialName(photoHeightField)
|
||||||
override var photoHeight: Int? = null
|
var photoHeight: Int? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
init {
|
fun setPhoto(
|
||||||
suggestedTipAmounts ?.let { _ ->
|
|
||||||
require(suggestedTipAmounts.size in suggestedTipAmountsLimit)
|
|
||||||
maxTipAmount ?.let { _ ->
|
|
||||||
require(
|
|
||||||
suggestedTipAmounts.none { it > maxTipAmount }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setPhoto(
|
|
||||||
photoUrl: String,
|
photoUrl: String,
|
||||||
photoSize: Long?,
|
photoSize: Long? = null,
|
||||||
photoWidth: Int?,
|
photoWidth: Int? = null,
|
||||||
photoHeight: Int?
|
photoHeight: Int? = null
|
||||||
) {
|
) {
|
||||||
this.photoUrl = photoUrl
|
this.photoUrl = photoUrl
|
||||||
this.photoSize = photoSize
|
this.photoSize = photoSize
|
||||||
@@ -115,7 +98,7 @@ data class SendInvoice(
|
|||||||
this.photoHeight = photoHeight
|
this.photoHeight = photoHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun unsetPhoto() {
|
fun unsetPhoto() {
|
||||||
photoUrl = null
|
photoUrl = null
|
||||||
photoSize = null
|
photoSize = null
|
||||||
photoWidth = null
|
photoWidth = null
|
||||||
|
|||||||
@@ -1,28 +1,23 @@
|
|||||||
package dev.inmo.tgbotapi.requests.send.polls
|
package dev.inmo.tgbotapi.requests.send.polls
|
||||||
|
|
||||||
import com.soywiz.klock.DateTime
|
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedOutput
|
|
||||||
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
|
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
|
||||||
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
|
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.*
|
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||||
import dev.inmo.tgbotapi.types.message.content.PollContent
|
import dev.inmo.tgbotapi.types.message.content.PollContent
|
||||||
import dev.inmo.tgbotapi.types.polls.*
|
import dev.inmo.tgbotapi.types.polls.*
|
||||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
import dev.inmo.tgbotapi.utils.fullListOfSubSource
|
||||||
|
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
||||||
|
import com.soywiz.klock.DateTime
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PollContent>> = TelegramBotAPIMessageDeserializationStrategyClass()
|
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PollContent>> = TelegramBotAPIMessageDeserializationStrategyClass()
|
||||||
|
|
||||||
private inline val ApproximateScheduledCloseInfo.openPeriod
|
|
||||||
get() = openDuration.millisecondsLong.div(1000)
|
|
||||||
private inline val ExactScheduledCloseInfo.closeDate
|
|
||||||
get() = closeDateTime.unixMillisLong.div(1000)
|
|
||||||
|
|
||||||
private fun checkPollInfo(
|
private fun checkPollInfo(
|
||||||
question: String,
|
question: String,
|
||||||
options: List<String>
|
options: List<String>
|
||||||
@@ -48,7 +43,6 @@ fun SendPoll(
|
|||||||
isClosed: Boolean = false,
|
isClosed: Boolean = false,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = SendRegularPoll(
|
) = SendRegularPoll(
|
||||||
chatId,
|
chatId,
|
||||||
@@ -56,7 +50,6 @@ fun SendPoll(
|
|||||||
options,
|
options,
|
||||||
isAnonymous,
|
isAnonymous,
|
||||||
isClosed,
|
isClosed,
|
||||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
|
||||||
disableNotification = disableNotification,
|
disableNotification = disableNotification,
|
||||||
replyToMessageId = replyToMessageId,
|
replyToMessageId = replyToMessageId,
|
||||||
replyMarkup = replyMarkup
|
replyMarkup = replyMarkup
|
||||||
@@ -70,7 +63,6 @@ fun Poll.createRequest(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean = false,
|
disableNotification: Boolean = false,
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
replyMarkup: KeyboardMarkup? = null
|
||||||
) = when (this) {
|
) = when (this) {
|
||||||
is RegularPoll -> SendRegularPoll(
|
is RegularPoll -> SendRegularPoll(
|
||||||
@@ -83,7 +75,6 @@ fun Poll.createRequest(
|
|||||||
scheduledCloseInfo,
|
scheduledCloseInfo,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
is QuizPoll -> correctOptionId ?.let { correctOptionId ->
|
is QuizPoll -> correctOptionId ?.let { correctOptionId ->
|
||||||
@@ -94,11 +85,11 @@ fun Poll.createRequest(
|
|||||||
correctOptionId,
|
correctOptionId,
|
||||||
isAnonymous,
|
isAnonymous,
|
||||||
isClosed,
|
isClosed,
|
||||||
textSources,
|
explanation ?.fullListOfSubSource(explanationEntities) ?.justTextSources() ?.toMarkdownV2Captions() ?.firstOrNull(),
|
||||||
|
MarkdownV2,
|
||||||
scheduledCloseInfo,
|
scheduledCloseInfo,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
} ?: SendRegularPoll(
|
} ?: SendRegularPoll(
|
||||||
@@ -111,7 +102,6 @@ fun Poll.createRequest(
|
|||||||
scheduledCloseInfo,
|
scheduledCloseInfo,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
is UnknownPollType -> SendRegularPoll(
|
is UnknownPollType -> SendRegularPoll(
|
||||||
@@ -124,7 +114,6 @@ fun Poll.createRequest(
|
|||||||
scheduledCloseInfo,
|
scheduledCloseInfo,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -145,23 +134,12 @@ sealed class SendPoll : SendMessageRequest<ContentMessage<PollContent>>,
|
|||||||
abstract val options: List<String>
|
abstract val options: List<String>
|
||||||
abstract val isAnonymous: Boolean
|
abstract val isAnonymous: Boolean
|
||||||
abstract val isClosed: Boolean
|
abstract val isClosed: Boolean
|
||||||
|
abstract val closeInfo: ScheduledCloseInfo?
|
||||||
abstract val type: String
|
abstract val type: String
|
||||||
|
|
||||||
internal abstract val openPeriod: LongSeconds?
|
internal abstract val openPeriod: LongSeconds?
|
||||||
internal abstract val closeDate: LongSeconds?
|
internal abstract val closeDate: LongSeconds?
|
||||||
|
|
||||||
protected val creationDate = DateTime.now()
|
|
||||||
open val closeInfo: ScheduledCloseInfo?
|
|
||||||
get() {
|
|
||||||
val openPeriod = openPeriod
|
|
||||||
val closeDate = closeDate
|
|
||||||
return when {
|
|
||||||
openPeriod != null -> openPeriod.asApproximateScheduledCloseInfo(creationDate)
|
|
||||||
closeDate != null -> closeDate.asExactScheduledCloseInfo
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun method(): String = "sendPoll"
|
override fun method(): String = "sendPoll"
|
||||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<PollContent>>
|
override val resultDeserializer: DeserializationStrategy<ContentMessage<PollContent>>
|
||||||
get() = commonResultDeserializer
|
get() = commonResultDeserializer
|
||||||
@@ -181,16 +159,12 @@ data class SendRegularPoll(
|
|||||||
override val isClosed: Boolean = false,
|
override val isClosed: Boolean = false,
|
||||||
@SerialName(allowsMultipleAnswersField)
|
@SerialName(allowsMultipleAnswersField)
|
||||||
val allowMultipleAnswers: Boolean = false,
|
val allowMultipleAnswers: Boolean = false,
|
||||||
@SerialName(openPeriodField)
|
@Transient
|
||||||
override val openPeriod: LongSeconds?= null,
|
override val closeInfo: ScheduledCloseInfo? = null,
|
||||||
@SerialName(closeDateField)
|
|
||||||
override val closeDate: LongSeconds?,
|
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendPoll() {
|
) : SendPoll() {
|
||||||
@@ -198,135 +172,22 @@ data class SendRegularPoll(
|
|||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
|
|
||||||
|
@SerialName(openPeriodField)
|
||||||
|
override val openPeriod: LongSeconds?
|
||||||
|
= (closeInfo as? ApproximateScheduledCloseInfo) ?.openDuration ?.millisecondsLong ?.div(1000)
|
||||||
|
|
||||||
|
@SerialName(closeDateField)
|
||||||
|
override val closeDate: LongSeconds?
|
||||||
|
= (closeInfo as? ExactScheduledCloseInfo) ?.closeDateTime ?.unixMillisLong ?.div(1000)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
checkPollInfo(question, options)
|
checkPollInfo(question, options)
|
||||||
closeInfo ?.checkSendData()
|
closeInfo ?.checkSendData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SendRegularPoll(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
question: String,
|
|
||||||
options: List<String>,
|
|
||||||
isAnonymous: Boolean = true,
|
|
||||||
isClosed: Boolean = false,
|
|
||||||
allowMultipleAnswers: Boolean = false,
|
|
||||||
closeInfo: ScheduledCloseInfo? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendRegularPoll(
|
|
||||||
chatId,
|
|
||||||
question,
|
|
||||||
options,
|
|
||||||
isAnonymous,
|
|
||||||
isClosed,
|
|
||||||
allowMultipleAnswers,
|
|
||||||
(closeInfo as? ApproximateScheduledCloseInfo) ?.openPeriod,
|
|
||||||
(closeInfo as? ExactScheduledCloseInfo) ?.closeDate,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun SendQuizPoll(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
question: String,
|
|
||||||
options: List<String>,
|
|
||||||
correctOptionId: Int,
|
|
||||||
isAnonymous: Boolean = true,
|
|
||||||
isClosed: Boolean = false,
|
|
||||||
explanation: String? = null,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
closeInfo: ScheduledCloseInfo? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendQuizPoll(
|
|
||||||
chatId,
|
|
||||||
question,
|
|
||||||
options,
|
|
||||||
correctOptionId,
|
|
||||||
isAnonymous,
|
|
||||||
isClosed,
|
|
||||||
explanation,
|
|
||||||
parseMode,
|
|
||||||
null,
|
|
||||||
closeInfo,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
fun SendQuizPoll(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
question: String,
|
|
||||||
options: List<String>,
|
|
||||||
correctOptionId: Int,
|
|
||||||
isAnonymous: Boolean = true,
|
|
||||||
isClosed: Boolean = false,
|
|
||||||
entities: List<TextSource>,
|
|
||||||
closeInfo: ScheduledCloseInfo? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendQuizPoll(
|
|
||||||
chatId,
|
|
||||||
question,
|
|
||||||
options,
|
|
||||||
correctOptionId,
|
|
||||||
isAnonymous,
|
|
||||||
isClosed,
|
|
||||||
entities.makeString(),
|
|
||||||
null,
|
|
||||||
entities.toRawMessageEntities(),
|
|
||||||
closeInfo,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
internal fun SendQuizPoll(
|
|
||||||
chatId: ChatIdentifier,
|
|
||||||
question: String,
|
|
||||||
options: List<String>,
|
|
||||||
correctOptionId: Int,
|
|
||||||
isAnonymous: Boolean = true,
|
|
||||||
isClosed: Boolean = false,
|
|
||||||
explanation: String? = null,
|
|
||||||
parseMode: ParseMode? = null,
|
|
||||||
rawEntities: List<RawMessageEntity>? = null,
|
|
||||||
closeInfo: ScheduledCloseInfo? = null,
|
|
||||||
disableNotification: Boolean = false,
|
|
||||||
replyToMessageId: MessageIdentifier? = null,
|
|
||||||
allowSendingWithoutReply: Boolean? = null,
|
|
||||||
replyMarkup: KeyboardMarkup? = null
|
|
||||||
) = SendQuizPoll(
|
|
||||||
chatId,
|
|
||||||
question,
|
|
||||||
options,
|
|
||||||
correctOptionId,
|
|
||||||
isAnonymous,
|
|
||||||
isClosed,
|
|
||||||
explanation,
|
|
||||||
parseMode,
|
|
||||||
rawEntities,
|
|
||||||
(closeInfo as? ApproximateScheduledCloseInfo) ?.openPeriod,
|
|
||||||
(closeInfo as? ExactScheduledCloseInfo) ?.closeDate,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SendQuizPoll internal constructor(
|
data class SendQuizPoll(
|
||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(questionField)
|
@SerialName(questionField)
|
||||||
@@ -340,30 +201,29 @@ data class SendQuizPoll internal constructor(
|
|||||||
@SerialName(isClosedField)
|
@SerialName(isClosedField)
|
||||||
override val isClosed: Boolean = false,
|
override val isClosed: Boolean = false,
|
||||||
@SerialName(explanationField)
|
@SerialName(explanationField)
|
||||||
override val text: String? = null,
|
override val explanation: String? = null,
|
||||||
@SerialName(explanationParseModeField)
|
@SerialName(explanationParseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
@SerialName(explanationEntitiesField)
|
@Transient
|
||||||
private val rawEntities: List<RawMessageEntity>? = null,
|
override val closeInfo: ScheduledCloseInfo? = null,
|
||||||
@SerialName(openPeriodField)
|
|
||||||
override val openPeriod: LongSeconds? = null,
|
|
||||||
@SerialName(closeDateField)
|
|
||||||
override val closeDate: LongSeconds? = null,
|
|
||||||
@SerialName(disableNotificationField)
|
@SerialName(disableNotificationField)
|
||||||
override val disableNotification: Boolean = false,
|
override val disableNotification: Boolean = false,
|
||||||
@SerialName(replyToMessageIdField)
|
@SerialName(replyToMessageIdField)
|
||||||
override val replyToMessageId: MessageIdentifier? = null,
|
override val replyToMessageId: MessageIdentifier? = null,
|
||||||
@SerialName(allowSendingWithoutReplyField)
|
|
||||||
override val allowSendingWithoutReply: Boolean? = null,
|
|
||||||
@SerialName(replyMarkupField)
|
@SerialName(replyMarkupField)
|
||||||
override val replyMarkup: KeyboardMarkup? = null
|
override val replyMarkup: KeyboardMarkup? = null
|
||||||
) : SendPoll(), TextedOutput {
|
) : SendPoll(), ExplainedOutput {
|
||||||
override val type: String = quizPollType
|
override val type: String = quizPollType
|
||||||
override val requestSerializer: SerializationStrategy<*>
|
override val requestSerializer: SerializationStrategy<*>
|
||||||
get() = serializer()
|
get() = serializer()
|
||||||
override val textSources: List<TextSource>? by lazy {
|
|
||||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
@SerialName(openPeriodField)
|
||||||
}
|
override val openPeriod: LongSeconds?
|
||||||
|
= (closeInfo as? ApproximateScheduledCloseInfo) ?.openDuration ?.millisecondsLong ?.div(1000)
|
||||||
|
|
||||||
|
@SerialName(closeDateField)
|
||||||
|
override val closeDate: LongSeconds?
|
||||||
|
= (closeInfo as? ExactScheduledCloseInfo) ?.closeDateTime ?.unixMillisLong ?.div(1000)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
checkPollInfo(question, options)
|
checkPollInfo(question, options)
|
||||||
@@ -373,9 +233,9 @@ data class SendQuizPoll internal constructor(
|
|||||||
throw IllegalArgumentException("Correct option id must be in range of $correctOptionIdRange, but actual " +
|
throw IllegalArgumentException("Correct option id must be in range of $correctOptionIdRange, but actual " +
|
||||||
"value is $correctOptionId")
|
"value is $correctOptionId")
|
||||||
}
|
}
|
||||||
if (text != null && text.length !in explanationLimit) {
|
if (explanation != null && explanation.length !in explanationLimit) {
|
||||||
error("Quiz poll explanation size must be in range $explanationLimit," +
|
error("Quiz poll explanation size must be in range $explanationLimit," +
|
||||||
"but actual explanation contains ${text.length} symbols")
|
"but actual explanation contains ${explanation.length} symbols")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user