diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c2d31b45c..5866bd1e9b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# TelegramBotAPI changelog
+## 0.37.0
+
+* `Common`:
+ * `Version`:
+ * `Klock`: `2.4.6` -> `2.4.7`
+ * `Ktor`: `1.6.4` -> `1.6.5`
+ * `MicroUtils`: `0.7.3` -> `0.8.1`
+* `Core`:
+ * Replacement of simple `CreateChatInviteLink` and `EditChatInviteLink` with several new:
+ * `CreateChatInviteLinkSimple`
+ * `CreateChatInviteLinkWithLimitedMembers`
+ * `CreateChatInviteLinkWithJoinRequest`
+ * `EditChatInviteLinkSimple`
+ * `EditChatInviteLinkWithLimitedMembers`
+ * `EditChatInviteLinkWithJoinRequest`
+
## 0.36.1
* `Common`:
diff --git a/README.md b/README.md
index 49d0c4420c..947bfe1a7d 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,11 @@
-[Participate in our common survey ☺](https://forms.gle/q6Xf8K3fD1pPsYUw9)
+# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-5.4-blue)](https://core.telegram.org/bots/api-changelog#november-5-2021)
-# TelegramBotAPI
-
-- [TelegramBotAPI](#telegrambotapi)
- * [Examples](#examples)
- + [Most common example](#most-common-example)
- + [Handling only last messages](#handling-only-last-messages)
- + [Build a little bit more complex behaviour](#build-a-little-bit-more-complex-behaviour)
- + [More examples](#more-examples)
-
-Table of contents generated with markdown-toc
+| [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://github.com/InsanusMokrassar/TelegramBotAPI/workflows/Build/badge.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue)](https://forms.gle/2Hex2ynbHWHhi1KY7) [![Chat in Telegram](https://img.shields.io/static/v1?label=Telegram&message=Chat&color=blue)](https://t.me/InMoTelegramBotAPI) |
+|:---:|
+| [![Create bot](https://img.shields.io/static/v1?label=Github&message=Template&color=blue)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![Examples](https://img.shields.io/static/v1?label=Github&message=Examples&color=blue)](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Bookstack&message=Tutorial&color=blue)](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
Hello! This is a set of libraries for working with Telegram Bot API.
-| Common info | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://github.com/InsanusMokrassar/TelegramBotAPI/workflows/Build/badge.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|
-| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| Useful links | [![Chat in Telegram](https://img.shields.io/static/v1?label=Talk&message=Telegram&color=blue)](https://t.me/InMoTelegramBotAPI) [![Create bot](https://img.shields.io/static/v1?label=Github&message=Template&color=blue)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![KDocs](https://img.shields.io/static/v1?label=Open&message=kdocs&color=blue)](https://tgbotapi.inmo.dev/index.html) [Examples](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/), [Mini tutorial](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
-| TelegramBotAPI Core status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
-| TelegramBotAPI API Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.api) |
-| TelegramBotAPI Util Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.utils) |
-| TelegramBotAPI Behaviour Builder Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.behaviour_builder/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.behaviour_builder) |
-| TelegramBotAPI Behaviour Builder FSM Extensions status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.behaviour_builder.fsm/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.behaviour_builder.fsm) |
-| TelegramBotAPI All status | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) |
-
## Examples
There are several things you need to do to launch examples below:
diff --git a/gradle.properties b/gradle.properties
index b9adc1ccd7..0ebf2720ed 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -8,15 +8,15 @@ kotlin.incremental.js=true
kotlin_version=1.5.31
kotlin_coroutines_version=1.5.2
kotlin_serialisation_runtime_version=1.3.0
-klock_version=2.4.6
+klock_version=2.4.7
uuid_version=0.3.1
-ktor_version=1.6.4
+ktor_version=1.6.5
-micro_utils_version=0.7.3
+micro_utils_version=0.8.1
javax_activation_version=1.1.1
library_group=dev.inmo
-library_version=0.36.1
+library_version=0.37.0
github_release_plugin_version=2.2.12
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8ad73a75c0..e7fa36715f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/ApproveChatJoinRequest.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/ApproveChatJoinRequest.kt
new file mode 100644
index 0000000000..e42e84509c
--- /dev/null
+++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/ApproveChatJoinRequest.kt
@@ -0,0 +1,39 @@
+package dev.inmo.tgbotapi.extensions.api.chat.invite_links
+
+import dev.inmo.tgbotapi.bot.TelegramBot
+import dev.inmo.tgbotapi.requests.chat.invite_links.ApproveChatJoinRequest
+import dev.inmo.tgbotapi.types.*
+import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
+import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
+
+suspend fun TelegramBot.approveChatJoinRequest(
+ chatId: ChatIdentifier,
+ userId: UserId
+) = execute(ApproveChatJoinRequest(chatId, userId))
+
+suspend fun TelegramBot.approveChatJoinRequest(
+ chat: PublicChat,
+ userId: UserId
+) = approveChatJoinRequest(chat.id, userId)
+
+suspend fun TelegramBot.approveChatJoinRequest(
+ chatId: ChatIdentifier,
+ user: User
+) = approveChatJoinRequest(chatId, user.id)
+
+suspend fun TelegramBot.approveChatJoinRequest(
+ chat: PublicChat,
+ user: User
+) = approveChatJoinRequest(chat.id, user.id)
+
+suspend fun TelegramBot.approveChatJoinRequest(
+ chatJoinRequest: ChatJoinRequest
+) = approveChatJoinRequest(chatJoinRequest.chat, chatJoinRequest.user)
+
+suspend fun TelegramBot.approve(
+ chatJoinRequest: ChatJoinRequest
+) = approveChatJoinRequest(chatJoinRequest)
+
+suspend fun TelegramBot.approveChatJoinRequest(
+ chatJoinRequestUpdate: ChatJoinRequestUpdate
+) = approveChatJoinRequest(chatJoinRequestUpdate.data)
diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/CreateChatInviteLink.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/CreateChatInviteLink.kt
index 93ed35d244..709405fc71 100644
--- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/CreateChatInviteLink.kt
+++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/CreateChatInviteLink.kt
@@ -6,26 +6,78 @@ import dev.inmo.tgbotapi.requests.chat.invite_links.CreateChatInviteLink
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
-suspend fun TelegramBot.createChatInviteLink(
+suspend fun TelegramBot.createChatInviteLinkUnlimited(
chatId: ChatIdentifier,
- expiration: TelegramDate? = null,
- membersLimit: MembersLimit? = null
-) = execute(CreateChatInviteLink(chatId, expiration, membersLimit))
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = execute(CreateChatInviteLink.unlimited(chatId, name, expiration))
-suspend fun TelegramBot.createChatInviteLink(
+suspend fun TelegramBot.createChatInviteLinkUnlimited(
chat: PublicChat,
+ name: String? = null,
expiration: TelegramDate? = null,
- membersLimit: MembersLimit? = null
-) = createChatInviteLink(chat.id, expiration, membersLimit)
+) = createChatInviteLinkUnlimited(chat.id, name, expiration)
-suspend fun TelegramBot.createChatInviteLink(
+suspend fun TelegramBot.createChatInviteLinkUnlimited(
chatId: ChatIdentifier,
expiration: DateTime,
- membersLimit: MembersLimit? = null
-) = createChatInviteLink(chatId, expiration.toTelegramDate(), membersLimit)
+ name: String? = null,
+) = createChatInviteLinkUnlimited(chatId, name, expiration.toTelegramDate())
-suspend fun TelegramBot.createChatInviteLink(
+suspend fun TelegramBot.createChatInviteLinkUnlimited(
chat: PublicChat,
expiration: DateTime,
- membersLimit: MembersLimit? = null
-) = createChatInviteLink(chat.id, expiration.toTelegramDate(), membersLimit)
+ name: String? = null
+) = createChatInviteLinkUnlimited(chat.id, name, expiration.toTelegramDate())
+
+suspend fun TelegramBot.createChatInviteLinkWithLimitedMembers(
+ chatId: ChatIdentifier,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = execute(CreateChatInviteLink.withLimitedMembers(chatId, membersLimit, name, expiration))
+
+suspend fun TelegramBot.createChatInviteLinkWithLimitedMembers(
+ chat: PublicChat,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = createChatInviteLinkWithLimitedMembers(chat.id, membersLimit, name, expiration)
+
+suspend fun TelegramBot.createChatInviteLinkWithLimitedMembers(
+ chatId: ChatIdentifier,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+) = createChatInviteLinkWithLimitedMembers(chatId, membersLimit, name, expiration.toTelegramDate())
+
+suspend fun TelegramBot.createChatInviteLinkWithLimitedMembers(
+ chat: PublicChat,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+) = createChatInviteLinkWithLimitedMembers(chat.id, membersLimit, name, expiration.toTelegramDate())
+
+suspend fun TelegramBot.createChatInviteLinkWithJoinRequest(
+ chatId: ChatIdentifier,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = execute(CreateChatInviteLink.withJoinRequest(chatId, name, expiration))
+
+suspend fun TelegramBot.createChatInviteLinkWithJoinRequest(
+ chat: PublicChat,
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = createChatInviteLinkWithJoinRequest(chat.id, name, expiration)
+
+suspend fun TelegramBot.createChatInviteLinkWithJoinRequest(
+ chatId: ChatIdentifier,
+ expiration: DateTime,
+ name: String? = null,
+) = createChatInviteLinkWithJoinRequest(chatId, name, expiration.toTelegramDate())
+
+suspend fun TelegramBot.createChatInviteLinkWithJoinRequest(
+ chat: PublicChat,
+ expiration: DateTime,
+ name: String? = null,
+) = createChatInviteLinkWithJoinRequest(chat.id, name, expiration.toTelegramDate())
diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/DeclineChatJoinRequest.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/DeclineChatJoinRequest.kt
new file mode 100644
index 0000000000..b6ca8a888b
--- /dev/null
+++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/DeclineChatJoinRequest.kt
@@ -0,0 +1,40 @@
+package dev.inmo.tgbotapi.extensions.api.chat.invite_links
+
+import dev.inmo.tgbotapi.bot.TelegramBot
+import dev.inmo.tgbotapi.requests.chat.invite_links.ApproveChatJoinRequest
+import dev.inmo.tgbotapi.requests.chat.invite_links.DeclineChatJoinRequest
+import dev.inmo.tgbotapi.types.*
+import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
+import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
+
+suspend fun TelegramBot.declineChatJoinRequest(
+ chatId: ChatIdentifier,
+ userId: UserId
+) = execute(DeclineChatJoinRequest(chatId, userId))
+
+suspend fun TelegramBot.declineChatJoinRequest(
+ chat: PublicChat,
+ userId: UserId
+) = declineChatJoinRequest(chat.id, userId)
+
+suspend fun TelegramBot.declineChatJoinRequest(
+ chatId: ChatIdentifier,
+ user: User
+) = declineChatJoinRequest(chatId, user.id)
+
+suspend fun TelegramBot.declineChatJoinRequest(
+ chat: PublicChat,
+ user: User
+) = declineChatJoinRequest(chat.id, user.id)
+
+suspend fun TelegramBot.declineChatJoinRequest(
+ chatJoinRequest: ChatJoinRequest
+) = declineChatJoinRequest(chatJoinRequest.chat, chatJoinRequest.user)
+
+suspend fun TelegramBot.decline(
+ chatJoinRequest: ChatJoinRequest
+) = declineChatJoinRequest(chatJoinRequest)
+
+suspend fun TelegramBot.declineChatJoinRequest(
+ chatJoinRequestUpdate: ChatJoinRequestUpdate
+) = declineChatJoinRequest(chatJoinRequestUpdate.data)
diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/EditChatInviteLink.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/EditChatInviteLink.kt
index 027a54360f..26a22a08ef 100644
--- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/EditChatInviteLink.kt
+++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/chat/invite_links/EditChatInviteLink.kt
@@ -6,58 +6,178 @@ import dev.inmo.tgbotapi.requests.chat.invite_links.EditChatInviteLink
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
-suspend fun TelegramBot.editChatInviteLink(
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
chatId: ChatIdentifier,
previousLink: String,
- expiration: TelegramDate? = null,
- membersLimit: MembersLimit? = null
-) = execute(EditChatInviteLink(chatId, previousLink, expiration, membersLimit))
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = execute(EditChatInviteLink.unlimited(chatId, previousLink, name, expiration))
-suspend fun TelegramBot.editChatInviteLink(
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
chat: PublicChat,
previousLink: String,
+ name: String? = null,
expiration: TelegramDate? = null,
- membersLimit: MembersLimit? = null
-) = editChatInviteLink(chat.id, previousLink, expiration, membersLimit)
+) = editChatInviteLinkUnlimited(chat.id, previousLink, name, expiration)
-suspend fun TelegramBot.editChatInviteLink(
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
chatId: ChatIdentifier,
previousLink: String,
expiration: DateTime,
- membersLimit: MembersLimit? = null
-) = editChatInviteLink(chatId, previousLink, expiration.toTelegramDate(), membersLimit)
+ name: String? = null,
+) = editChatInviteLinkUnlimited(chatId, previousLink, name , expiration.toTelegramDate())
-suspend fun TelegramBot.editChatInviteLink(
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
chat: PublicChat,
previousLink: String,
expiration: DateTime,
- membersLimit: MembersLimit? = null
-) = editChatInviteLink(chat.id, previousLink, expiration.toTelegramDate(), membersLimit)
+ name: String? = null,
+) = editChatInviteLinkUnlimited(chat.id, previousLink, name , expiration.toTelegramDate())
-suspend fun TelegramBot.editChatInviteLink(
- chat: ChatIdentifier,
- previousLink: ChatInviteLink,
- expiration: TelegramDate? = previousLink.expirationDateTime ?.toTelegramDate(),
- membersLimit: MembersLimit? = previousLink.membersLimit
-) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chatId: ChatIdentifier,
+ previousLink: String,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = execute(EditChatInviteLink.withLimitedMembers(chatId, previousLink, membersLimit, name, expiration))
-suspend fun TelegramBot.editChatInviteLink(
- chat: ChatIdentifier,
- previousLink: ChatInviteLink,
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chat: PublicChat,
+ previousLink: String,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = editChatInviteLinkWithLimitedMembers(chat.id, previousLink, membersLimit, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chatId: ChatIdentifier,
+ previousLink: String,
+ membersLimit: MembersLimit,
expiration: DateTime,
- membersLimit: MembersLimit? = previousLink.membersLimit
-) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
+ name: String? = null,
+) = editChatInviteLinkWithLimitedMembers(chatId, previousLink, membersLimit, name , expiration.toTelegramDate())
-suspend fun TelegramBot.editChatInviteLink(
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chat: PublicChat,
+ previousLink: String,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithLimitedMembers(chat.id, previousLink, membersLimit, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chatId: ChatIdentifier,
+ previousLink: String,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = execute(EditChatInviteLink.withJoinRequest(chatId, previousLink, name, expiration))
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chat: PublicChat,
+ previousLink: String,
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = editChatInviteLinkWithJoinRequest(chat.id, previousLink, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chatId: ChatIdentifier,
+ previousLink: String,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithJoinRequest(chatId, previousLink, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chat: PublicChat,
+ previousLink: String,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithJoinRequest(chat.id, previousLink, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
+ chatId: ChatIdentifier,
+ previousLink: ChatInviteLink,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = editChatInviteLinkUnlimited(chatId, previousLink.inviteLink, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
chat: PublicChat,
previousLink: ChatInviteLink,
- expiration: TelegramDate? = previousLink.expirationDateTime ?.toTelegramDate(),
- membersLimit: MembersLimit? = previousLink.membersLimit
-) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = editChatInviteLinkUnlimited(chat.id, previousLink, name, expiration)
-suspend fun TelegramBot.editChatInviteLink(
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
+ chatId: ChatIdentifier,
+ previousLink: ChatInviteLink,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkUnlimited(chatId, previousLink, name, expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkUnlimited(
chat: PublicChat,
previousLink: ChatInviteLink,
expiration: DateTime,
- membersLimit: MembersLimit? = previousLink.membersLimit
-) = editChatInviteLink(chat, previousLink.inviteLink, expiration, membersLimit)
+ name: String? = null,
+) = editChatInviteLinkUnlimited(chat.id, previousLink, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chatId: ChatIdentifier,
+ previousLink: ChatInviteLink,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = editChatInviteLinkWithLimitedMembers(chatId, previousLink.inviteLink, membersLimit, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chat: PublicChat,
+ previousLink: ChatInviteLink,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = editChatInviteLinkWithLimitedMembers(chat.id, previousLink, membersLimit, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chatId: ChatIdentifier,
+ previousLink: ChatInviteLink,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithLimitedMembers(chatId, previousLink, membersLimit, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkWithLimitedMembers(
+ chat: PublicChat,
+ previousLink: ChatInviteLink,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithLimitedMembers(chat.id, previousLink, membersLimit, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chatId: ChatIdentifier,
+ previousLink: ChatInviteLink,
+ name: String? = null,
+ expiration: TelegramDate? = null
+) = editChatInviteLinkWithJoinRequest(chatId, previousLink.inviteLink, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chat: PublicChat,
+ previousLink: ChatInviteLink,
+ name: String? = null,
+ expiration: TelegramDate? = null,
+) = editChatInviteLinkWithJoinRequest(chat.id, previousLink, name, expiration)
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chatId: ChatIdentifier,
+ previousLink: ChatInviteLink,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithJoinRequest(chatId, previousLink, name , expiration.toTelegramDate())
+
+suspend fun TelegramBot.editChatInviteLinkWithJoinRequest(
+ chat: PublicChat,
+ previousLink: ChatInviteLink,
+ expiration: DateTime,
+ name: String? = null,
+) = editChatInviteLinkWithJoinRequest(chat.id, previousLink, name , expiration.toTelegramDate())
diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendAction.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendAction.kt
index bf6af8adf9..c07ada572e 100644
--- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendAction.kt
+++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendAction.kt
@@ -100,3 +100,7 @@ suspend fun TelegramBot.sendActionUploadVideoNote(
chat: Chat
) = sendBotAction(chat, UploadVideoNoteAction)
+suspend fun TelegramBot.sendActionChooseStickerAction(
+ chat: Chat
+) = sendBotAction(chat, ChooseStickerAction)
+
diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt
index d4ebb42816..c247ad55c1 100644
--- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt
+++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt
@@ -59,6 +59,7 @@ suspend fun TelegramBot.withUploadDocumentAction(chatId: ChatId, block: Tele
suspend fun TelegramBot.withFindLocationAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, FindLocationAction, block)
suspend fun TelegramBot.withRecordVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, RecordVideoNoteAction, block)
suspend fun TelegramBot.withUploadVideoNoteAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, UploadVideoNoteAction, block)
+suspend fun TelegramBot.withChooseStickerAction(chatId: ChatId, block: TelegramBotActionCallback) = withAction(chatId, ChooseStickerAction, block)
suspend fun TelegramBot.withTypingAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, TypingAction, block)
@@ -71,3 +72,4 @@ suspend fun TelegramBot.withUploadDocumentAction(chat: Chat, block: Telegram
suspend fun TelegramBot.withFindLocationAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, FindLocationAction, block)
suspend fun TelegramBot.withRecordVideoNoteAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, RecordVideoNoteAction, block)
suspend fun TelegramBot.withUploadVideoNoteAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, UploadVideoNoteAction, block)
+suspend fun TelegramBot.withChooseStickerAction(chat: Chat, block: TelegramBotActionCallback) = withAction(chat, ChooseStickerAction, block)
diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt
index 69e4529dbb..be5cdb8923 100644
--- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt
+++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt
@@ -10,16 +10,6 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.*
-private suspend fun BehaviourContextWithFSM.launchStateHandling(
- state: State,
- contextUpdatesFlow: Flow,
- handlers: List>
-): State? {
- return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
- handleState(contextUpdatesFlow, state)
- }
-}
-
/**
* Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have
* one common flow of updates and must not lose updates between updates
@@ -27,9 +17,19 @@ private suspend fun BehaviourContextWithFSM.launchStateHandling(
* @see DefaultBehaviourContextWithFSM
* @see buildBehaviourWithFSM
*/
-interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
+interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
suspend fun start() = start(this)
+ suspend fun launchStateHandling(
+ state: T,
+ contextUpdatesFlow: Flow,
+ handlers: List>
+ ): T? {
+ return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
+ handleState(contextUpdatesFlow, state)
+ }
+ }
+
override fun copy(
bot: TelegramBot,
scope: CoroutineScope,
@@ -37,14 +37,14 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow?,
updatesFilter: BehaviourContextAndTypeReceiver?
- ): BehaviourContextWithFSM
+ ): BehaviourContextWithFSM
companion object {
- operator fun invoke(
+ operator fun invoke(
behaviourContext: BehaviourContext,
- handlers: List>,
- statesManager: StatesManager
- ) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers)
+ handlers: List>,
+ statesManager: StatesManager
+ ) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers)
}
}
@@ -52,23 +52,24 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
* Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as
* [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states
*/
-class DefaultBehaviourContextWithFSM(
+class DefaultBehaviourContextWithFSM(
private val behaviourContext: BehaviourContext,
- private val statesManager: StatesManager,
- private val handlers: List>
-) : BehaviourContext by behaviourContext, BehaviourContextWithFSM {
+ private val statesManager: StatesManager,
+ private val handlers: List>
+) : BehaviourContext by behaviourContext, BehaviourContextWithFSM {
private val updatesFlows = mutableMapOf>()
private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) {
allUpdatesFlow.accumulatorFlow(scope)
}
- override suspend fun StatesMachine.handleState(state: State): State? = launchStateHandling(
+
+ override suspend fun StatesMachine.handleState(state: T): T? = launchStateHandling(
state,
allUpdatesFlow,
handlers
)
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
- val statePerformer: suspend (State) -> Unit = { state: State ->
+ val statePerformer: suspend (T) -> Unit = { state: T ->
val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers)
if (newState != null) {
statesManager.update(state, newState)
@@ -94,7 +95,7 @@ class DefaultBehaviourContextWithFSM(
}
}
- override suspend fun startChain(state: State) {
+ override suspend fun startChain(state: T) {
statesManager.startChain(state)
}
@@ -105,7 +106,7 @@ class DefaultBehaviourContextWithFSM(
onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow?,
updatesFilter: BehaviourContextAndTypeReceiver?
- ): BehaviourContextWithFSM = BehaviourContextWithFSM(
+ ): BehaviourContextWithFSM = BehaviourContextWithFSM(
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter),
handlers,
statesManager
diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt
index a7e41bad85..7723b81c70 100644
--- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt
+++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt
@@ -14,14 +14,14 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlin.reflect.KClass
-class BehaviourContextWithFSMBuilder internal constructor(
- private val resultBehaviourContext: BehaviourContextWithFSM,
- private val handlers: MutableList>
-) : BehaviourContextWithFSM by resultBehaviourContext {
+class BehaviourContextWithFSMBuilder internal constructor(
+ private val resultBehaviourContext: BehaviourContextWithFSM,
+ private val handlers: MutableList>
+) : BehaviourContextWithFSM by resultBehaviourContext {
internal constructor(
baseBehaviourContext: BehaviourContext,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- handlers: MutableList> = mutableListOf()
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ handlers: MutableList> = mutableListOf()
) : this(DefaultBehaviourContextWithFSM(baseBehaviourContext, statesManager, handlers), handlers)
/**
@@ -31,7 +31,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourWithFSMStateHandlerHolder
* @see onStateOrSubstate
*/
- fun add(kClass: KClass, handler: BehaviourWithFSMStateHandler) {
+ fun add(kClass: KClass, handler: BehaviourWithFSMStateHandler) {
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, false, handler))
}
@@ -43,7 +43,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourWithFSMStateHandlerHolder
* @see strictlyOn
*/
- fun addStrict(kClass: KClass, handler: BehaviourWithFSMStateHandler) {
+ fun addStrict(kClass: KClass, handler: BehaviourWithFSMStateHandler) {
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, true, handler))
}
@@ -56,7 +56,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourContextWithFSMBuilder.add
*/
@Suppress("MemberVisibilityCanBePrivate")
- inline fun onStateOrSubstate(handler: BehaviourWithFSMStateHandler) {
+ inline fun onStateOrSubstate(handler: BehaviourWithFSMStateHandler) {
add(I::class, handler)
}
@@ -69,7 +69,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourContextWithFSMBuilder.addStrict
*/
@Suppress("MemberVisibilityCanBePrivate")
- inline fun strictlyOn(handler: BehaviourWithFSMStateHandler) {
+ inline fun strictlyOn(handler: BehaviourWithFSMStateHandler) {
addStrict(I::class, handler)
}
@@ -89,14 +89,14 @@ class BehaviourContextWithFSMBuilder internal constructor(
* start any updates retrieving. See [buildBehaviourWithFSMAndStartLongPolling] or
* [telegramBotWithBehaviourAndFSMAndStartLongPolling] in case you wish to start [longPolling] automatically
*/
-suspend fun TelegramBot.buildBehaviourWithFSM(
+suspend fun TelegramBot.buildBehaviourWithFSM(
upstreamUpdatesFlow: Flow? = null,
scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler? = null,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- presetHandlers: MutableList> = mutableListOf(),
- block: CustomBehaviourContextReceiver
-): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder(
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ presetHandlers: MutableList> = mutableListOf(),
+ block: CustomBehaviourContextReceiver, Unit>
+): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder(
DefaultBehaviourContext(
this,
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
@@ -111,14 +111,14 @@ suspend fun TelegramBot.buildBehaviourWithFSM(
* using [longPolling]. For [longPolling] will be used result [BehaviourContextWithFSM] for both parameters
* flowsUpdatesFilter and scope
*/
-suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
+suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
upstreamUpdatesFlow: Flow? = null,
scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler? = null,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- presetHandlers: MutableList> = mutableListOf(),
- block: CustomBehaviourContextReceiver
-): Pair = buildBehaviourWithFSM(
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ presetHandlers: MutableList> = mutableListOf(),
+ block: CustomBehaviourContextReceiver, Unit>
+): Pair, Job> = buildBehaviourWithFSM(
upstreamUpdatesFlow,
scope,
defaultExceptionsHandler,
@@ -151,14 +151,14 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate
*/
@PreviewFeature
-suspend fun TelegramBot.buildBehaviourWithFSM(
+suspend fun TelegramBot.buildBehaviourWithFSM(
flowUpdatesFilter: FlowsUpdatesFilter,
scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler? = null,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- presetHandlers: MutableList> = mutableListOf(),
- block: CustomBehaviourContextReceiver
-): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder(
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ presetHandlers: MutableList> = mutableListOf(),
+ block: CustomBehaviourContextReceiver, Unit>
+): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder(
DefaultBehaviourContext(
this,
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
@@ -180,12 +180,12 @@ suspend fun TelegramBot.buildBehaviourWithFSM(
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate
*/
@PreviewFeature
-suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
+suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler? = null,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- presetHandlers: MutableList> = mutableListOf(),
- block: CustomBehaviourContextReceiver
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ presetHandlers: MutableList> = mutableListOf(),
+ block: CustomBehaviourContextReceiver, Unit>
) = FlowsUpdatesFilter().let {
buildBehaviourWithFSM(
it,
diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler.kt
index c2e1b6f32f..93d0ccd6f4 100644
--- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler.kt
+++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler.kt
@@ -2,6 +2,6 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.fsm.common.*
-fun interface BehaviourWithFSMStateHandler {
- suspend fun BehaviourContextWithFSM.handleState(state: T): State?
+fun interface BehaviourWithFSMStateHandler {
+ suspend fun BehaviourContextWithFSM.handleState(state: I): O?
}
diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt
index 00a8d4a82a..788c1cf3c1 100644
--- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt
+++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt
@@ -19,10 +19,10 @@ import kotlin.reflect.KClass
* @param delegateTo This handler will be called in case [checkHandleable] returns true with class caster incoming
* [State] in [handleState]
*/
-class BehaviourWithFSMStateHandlerHolder(
+class BehaviourWithFSMStateHandlerHolder(
private val inputKlass: KClass,
private val strict: Boolean = false,
- private val delegateTo: BehaviourWithFSMStateHandler
+ private val delegateTo: BehaviourWithFSMStateHandler
) {
/**
* Check ability of [delegateTo] to handle this [state]
@@ -30,7 +30,7 @@ class BehaviourWithFSMStateHandlerHolder(
* @return When [state]::class exactly equals to [inputKlass] will always return true. Otherwise when [strict]
* mode is disabled, will be used [KClass.isInstance] of [inputKlass] for checking
*/
- fun checkHandleable(state: State) = state::class == inputKlass || (!strict && inputKlass.isInstance(state))
+ fun checkHandleable(state: O): Boolean = state::class == inputKlass || (!strict && inputKlass.isInstance(state))
/**
* Handling of state :)
@@ -38,10 +38,10 @@ class BehaviourWithFSMStateHandlerHolder(
* @param contextUpdatesFlow This [Flow] will be used as source of updates. By contract, this [Flow] must be common
* for all [State]s of incoming [state] [State.context] and for the whole chain inside of [BehaviourContextWithFSM]
*/
- suspend fun BehaviourContextWithFSM.handleState(
+ suspend fun BehaviourContextWithFSM.handleState(
contextUpdatesFlow: Flow,
- state: State
- ): State? {
+ state: O
+ ): O? {
val subscope = scope.LinkedSupervisorScope()
return with(copy(scope = subscope, upstreamUpdatesFlow = contextUpdatesFlow)) {
with(delegateTo) {
@@ -50,3 +50,8 @@ class BehaviourWithFSMStateHandlerHolder(
}
}
}
+
+inline fun BehaviourWithFSMStateHandlerHolder(
+ strict: Boolean = false,
+ delegateTo: BehaviourWithFSMStateHandler
+) = BehaviourWithFSMStateHandlerHolder(I::class, strict, delegateTo)
diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt
index e7ef4fd5b3..0c5b881580 100644
--- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt
+++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt
@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.coroutines.ExceptionHandler
+import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
@@ -28,16 +29,16 @@ import kotlin.coroutines.coroutineContext
* @see [buildBehaviourWithFSM]
* @see startGettingOfUpdatesByLongPolling
*/
-suspend fun telegramBotWithBehaviourAndFSM(
+suspend fun telegramBotWithBehaviourAndFSM(
token: String,
flowsUpdatesFilter: FlowsUpdatesFilter,
scope: CoroutineScope? = null,
apiUrl: String = telegramBotAPIDefaultUrl,
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
defaultExceptionsHandler: ExceptionHandler? = null,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- presetHandlers: MutableList> = mutableListOf(),
- block: CustomBehaviourContextReceiver
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ presetHandlers: MutableList> = mutableListOf(),
+ block: CustomBehaviourContextReceiver, Unit>
): TelegramBot = telegramBot(
token,
apiUrl,
@@ -64,15 +65,15 @@ suspend fun telegramBotWithBehaviourAndFSM(
* @see buildBehaviourWithFSMAndStartLongPolling
* @see startGettingOfUpdatesByLongPolling
*/
-suspend fun telegramBotWithBehaviourAndFSMAndStartLongPolling(
+suspend fun telegramBotWithBehaviourAndFSMAndStartLongPolling(
token: String,
scope: CoroutineScope? = null,
apiUrl: String = telegramBotAPIDefaultUrl,
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
defaultExceptionsHandler: ExceptionHandler? = null,
- statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
- presetHandlers: MutableList> = mutableListOf(),
- block: CustomBehaviourContextReceiver
+ statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
+ presetHandlers: MutableList> = mutableListOf(),
+ block: CustomBehaviourContextReceiver, Unit>
): Pair {
return telegramBot(
token,
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourBuilders.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourBuilders.kt
index e6111623bd..dd17203ef3 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourBuilders.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourBuilders.kt
@@ -27,7 +27,7 @@ expect var defaultCoroutineScopeProvider: () -> CoroutineScope
*/
@PreviewFeature
suspend fun TelegramBot.buildBehaviour(
- flowUpdatesFilter: FlowsUpdatesFilter,
+ flowUpdatesFilter: FlowsUpdatesFilter = FlowsUpdatesFilter(),
scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler? = null,
block: BehaviourContextReceiver
@@ -70,11 +70,3 @@ suspend fun TelegramBot.buildBehaviourWithLongPolling(
scope = scope
)
}
-
-@PreviewFeature
-@Deprecated("Renamed to buildBehaviourWithLongPolling")
-suspend fun TelegramBot.buildBehaviour(
- scope: CoroutineScope = defaultCoroutineScopeProvider(),
- defaultExceptionsHandler: ExceptionHandler? = null,
- block: BehaviourContextReceiver
-) = buildBehaviourWithLongPolling(scope, defaultExceptionsHandler, block)
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt
index 0b62483ba6..6d99c2c291 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt
@@ -55,13 +55,6 @@ interface BehaviourContext : FlowsUpdatesFilter, TelegramBot, CoroutineScope {
upstreamUpdatesFlow: Flow? = null,
updatesFilter: BehaviourContextAndTypeReceiver? = null
): BehaviourContext
-
- @Deprecated("This method is not recommended to use and will be removed in near release")
- fun copy(
- bot: TelegramBot,
- scope: CoroutineScope = this.scope,
- flowsUpdatesFilter: FlowsUpdatesFilter = this.flowsUpdatesFilter
- ): BehaviourContext = copy(upstreamUpdatesFlow = flowsUpdatesFilter.allUpdatesFlow)
}
class DefaultBehaviourContext(
@@ -113,30 +106,6 @@ inline fun BehaviourContext(
crossinline block: BehaviourContext.() -> T
) = DefaultBehaviourContext(bot, scope, upstreamUpdatesFlow = flowsUpdatesFilter.allUpdatesFlow).run(block)
-/**
- * Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [newFlowsUpdatesFilterSetUp] is provided and
- * [CoroutineScope] as new [BehaviourContext.scope]. You must do all subscription/running of longPolling manually.
- *
- * @param newFlowsUpdatesFilterSetUp As a parameter receives [FlowsUpdatesFilter] from old [this] [BehaviourContext.flowsUpdatesFilter]
- */
-@RiskFeature("It is recommended to use doInSubContextWithUpdatesFilter instead. " +
- "This method is low level and should not be used in case you are not pretty sure you need it.")
-@Deprecated("This method is useless and will not be used in future")
-suspend fun BC.doInSubContextWithFlowsUpdatesFilterSetup(
- newFlowsUpdatesFilterSetUp: CustomBehaviourContextAndTypeReceiver?,
- stopOnCompletion: Boolean = true,
- behaviourContextReceiver: CustomBehaviourContextReceiver
-): T = (copy(
- scope = LinkedSupervisorScope(),
-) as BC).run {
- withContext(coroutineContext) {
- newFlowsUpdatesFilterSetUp ?.let {
- it.apply { invoke(this@run, this@doInSubContextWithFlowsUpdatesFilterSetup.flowsUpdatesFilter) }
- }
- behaviourContextReceiver().also { if (stopOnCompletion) stop() }
- }
-}
-
/**
* Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [updatesFilter] is provided and
* [CoroutineScope] as new [BehaviourContext.scope]
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBot.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBot.kt
index b0ab06183d..6ab989cd08 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBot.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBot.kt
@@ -25,7 +25,7 @@ import kotlin.coroutines.coroutineContext
*/
suspend fun telegramBotWithBehaviour(
token: String,
- flowsUpdatesFilter: FlowsUpdatesFilter,
+ flowsUpdatesFilter: FlowsUpdatesFilter = FlowsUpdatesFilter(),
scope: CoroutineScope? = null,
apiUrl: String = telegramBotAPIDefaultUrl,
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
@@ -77,13 +77,3 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
)
}
}
-
-@Deprecated("Renamed to telegramBotWithBehaviourAndLongPolling")
-suspend fun telegramBotWithBehaviour(
- token: String,
- scope: CoroutineScope? = null,
- apiUrl: String = telegramBotAPIDefaultUrl,
- builder: KtorRequestsExecutorBuilder.() -> Unit = {},
- defaultExceptionsHandler: ExceptionHandler? = null,
- block: BehaviourContextReceiver
-) = telegramBotWithBehaviourAndLongPolling(token, scope, apiUrl, builder, defaultExceptionsHandler, block)
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitChatJoinRequest.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitChatJoinRequest.kt
new file mode 100644
index 0000000000..f3efaaf195
--- /dev/null
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitChatJoinRequest.kt
@@ -0,0 +1,51 @@
+package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
+
+import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
+import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
+import dev.inmo.tgbotapi.extensions.utils.*
+import dev.inmo.tgbotapi.requests.abstracts.Request
+import dev.inmo.tgbotapi.types.ChatJoinRequest
+import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
+import dev.inmo.tgbotapi.types.payments.ShippingQuery
+import kotlinx.coroutines.flow.toList
+
+typealias ChatJoinRequestsMapper = suspend ChatJoinRequest.() -> ChatJoinRequest?
+
+private suspend fun BehaviourContext.waitChatJoinRequests(
+ count: Int = 1,
+ initRequest: Request<*>? = null,
+ errorFactory: NullableRequestBuilder<*> = { null },
+ filter: SimpleFilter? = null,
+ mapper: suspend ChatJoinRequest.() -> O?
+): List = expectFlow(
+ initRequest,
+ count,
+ errorFactory
+) {
+ val data = it.asChatJoinRequestUpdate() ?.data
+ if (data != null && (filter == null || filter(data))) {
+ data.mapper().let(::listOfNotNull)
+ } else {
+ emptyList()
+ }
+}.toList().toList()
+
+
+suspend fun BehaviourContext.waitChatJoinRequests(
+ initRequest: Request<*>? = null,
+ errorFactory: NullableRequestBuilder<*> = { null },
+ count: Int = 1,
+ filter: SimpleFilter? = null,
+ mapper: ChatJoinRequestsMapper? = null
+) : List = waitChatJoinRequests(
+ count,
+ initRequest,
+ errorFactory,
+ filter
+) {
+ if (mapper == null) {
+ this
+ } else {
+ mapper(this)
+ }
+}
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt
index 8489961012..9ca984ccc2 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt
@@ -119,14 +119,6 @@ suspend fun BehaviourContext.waitEditedStaticLocation(
filter: SimpleFilter>? = null,
mapper: CommonMessageToContentMapper? = null
) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
-@Deprecated("Potentially, this trigger will never be used. Use `waitPollUpdates` instead")
-suspend fun BehaviourContext.waitEditedPoll(
- initRequest: Request<*>? = null,
- errorFactory: NullableRequestBuilder<*> = { null },
- count: Int = 1,
- filter: SimpleFilter>? = null,
- mapper: CommonMessageToContentMapper? = null
-) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper)
suspend fun BehaviourContext.waitEditedText(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterByChat.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterByChat.kt
index 370db3c006..c0877ce42b 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterByChat.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterByChat.kt
@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.filters
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.types.CallbackQuery.CallbackQuery
+import dev.inmo.tgbotapi.types.ChatJoinRequest
import dev.inmo.tgbotapi.types.ChatMemberUpdated
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
import dev.inmo.tgbotapi.types.message.abstracts.Message
@@ -54,3 +55,9 @@ val InlineQueryFilterByUser: BehaviourContextAndTwoTypesReceiver = { updated, update ->
update.sourceChat() ?.id == updated.chat.id
}
+/**
+ * Allow only events from the same chat as base [ChatMemberUpdated]
+ */
+val ChatJoinRequestFilterByChat: BehaviourContextAndTwoTypesReceiver = { updated, update ->
+ update.sourceChat() ?.id == updated.chat.id
+}
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ChatJoinRequestTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ChatJoinRequestTriggers.kt
new file mode 100644
index 0000000000..b201725d57
--- /dev/null
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ChatJoinRequestTriggers.kt
@@ -0,0 +1,34 @@
+package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
+
+import dev.inmo.tgbotapi.extensions.behaviour_builder.*
+import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.*
+import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
+import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.*
+import dev.inmo.tgbotapi.extensions.utils.asChatJoinRequestUpdate
+import dev.inmo.tgbotapi.extensions.utils.asShippingQueryUpdate
+import dev.inmo.tgbotapi.types.ChatJoinRequest
+import dev.inmo.tgbotapi.types.payments.ShippingQuery
+import dev.inmo.tgbotapi.types.update.abstracts.Update
+
+/**
+ * Please, remember that your bot must have `can_invite_users` to receive these requests
+ *
+ * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
+ * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
+ * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
+ * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
+ * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
+ * to combinate several filters
+ * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
+ * in one "stream". Output of [markerFactory] will be used as a key for "stream"
+ * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
+ * data
+ */
+suspend fun BC.onChatJoinRequest(
+ initialFilter: SimpleFilter? = null,
+ subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = ChatJoinRequestFilterByChat,
+ markerFactory: MarkerFactory = ByChatChatJoinRequestMarkerFactory,
+ scenarioReceiver: CustomBehaviourContextAndTypeReceiver
+) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
+ (it.asChatJoinRequestUpdate() ?.data) ?.let(::listOfNotNull)
+}
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EditedContentTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EditedContentTriggers.kt
index a78aa2ca76..ba36d62331 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EditedContentTriggers.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EditedContentTriggers.kt
@@ -166,19 +166,6 @@ suspend fun BC.onEditedLocation(
scenarioReceiver
)
-@Deprecated("Potentially, this trigger will never be used. Use `onPollUpdated` instead")
-suspend fun BC.onEditedPoll(
- initialFilter: CommonMessageFilter? = CommonMessageFilterExcludeMediaGroups,
- subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat,
- markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory,
- scenarioReceiver: CustomBehaviourContextAndTypeReceiver>
-)= onEditedContent(
- initialFilter,
- subcontextUpdatesFilter,
- markerFactory,
- scenarioReceiver
-)
-
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/QueryMarkerFactories.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/QueryMarkerFactories.kt
index ccb7cd7734..5f831e6fbd 100644
--- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/QueryMarkerFactories.kt
+++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/QueryMarkerFactories.kt
@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories
import dev.inmo.tgbotapi.types.CallbackQuery.CallbackQuery
+import dev.inmo.tgbotapi.types.ChatJoinRequest
import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery
import dev.inmo.tgbotapi.types.payments.ShippingQuery
@@ -8,6 +9,10 @@ object ByUserCallbackQueryMarkerFactory : MarkerFactory {
override suspend fun invoke(data: CallbackQuery) = data.user
}
+object ByChatChatJoinRequestMarkerFactory : MarkerFactory {
+ override suspend fun invoke(data: ChatJoinRequest) = data.chat
+}
+
object ByUserShippingQueryMarkerFactory : MarkerFactory {
override suspend fun invoke(data: ShippingQuery) = data.user
}
diff --git a/tgbotapi.core/README.md b/tgbotapi.core/README.md
index ac3a0a7e9e..23dd292ba0 100644
--- a/tgbotapi.core/README.md
+++ b/tgbotapi.core/README.md
@@ -21,10 +21,6 @@
Library for Object-Oriented and type-safe work with Telegram Bot API. Most part of some specific solves or unuseful
moments are describing by official [Telegram Bot API](https://core.telegram.org/bots/api).
-## 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).
-
## How to implement library?
Common ways to implement this library are presented here. In some cases it will require additional steps
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt
index b6d31e8875..e62250f706 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/AbstractRequestCallFactory.kt
@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.bot.Ktor.base
import dev.inmo.micro_utils.coroutines.safely
+import dev.inmo.micro_utils.coroutines.safelyWithResult
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.requests.GetUpdates
@@ -57,7 +58,7 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
val content = response.receive()
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
- return safely {
+ return safelyWithResult {
(responseObject.result?.let {
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
} ?: response.let {
@@ -67,7 +68,7 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
"Can't get result object from $content"
)
})
- }
+ }.getOrThrow()
}
}
@@ -76,4 +77,4 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
urlsKeeper: TelegramAPIUrlsKeeper,
request: Request
): Any?
-}
\ No newline at end of file
+}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/abstracts/ChatInviteLinkRequest.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/abstracts/ChatInviteLinkRequest.kt
index a45d428a8d..a1b0a9885b 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/abstracts/ChatInviteLinkRequest.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/abstracts/ChatInviteLinkRequest.kt
@@ -5,16 +5,27 @@ import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.DeserializationStrategy
-interface ChatInviteLinkRequest : SimpleRequest {
+interface ChatInviteLinkRequest : SimpleRequest {
val chatId: ChatIdentifier
-
- override val resultDeserializer: DeserializationStrategy
- get() = CommonInviteLink.serializer()
}
-interface KnownChatInviteLinkRequest : ChatInviteLinkRequest {
+
+interface KnownChatInviteLinkRequest : ChatInviteLinkRequest {
val inviteLink: String
}
-interface EditChatInviteLinkRequest : ChatInviteLinkRequest {
- val expireDate: DateTime?
- val membersLimit: MembersLimit?
+
+interface LimitedMembersChatInviteLinkRequest : ChatInviteLinkRequest {
+ val membersLimit: MembersLimit
+
+ override val resultDeserializer: DeserializationStrategy
+ get() = ChatInviteLinkWithLimitedMembers.serializer()
+}
+
+interface WithJoinRequestChatInviteLinkRequest : ChatInviteLinkRequest {
+ override val resultDeserializer: DeserializationStrategy
+ get() = ChatInviteLinkWithJoinRequest.serializer()
+}
+
+interface EditChatInviteLinkRequest : ChatInviteLinkRequest {
+ val expireDate: DateTime?
+ val name: String?
}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/ChatJoinRequestAnswer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/ChatJoinRequestAnswer.kt
new file mode 100644
index 0000000000..ab4c705187
--- /dev/null
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/ChatJoinRequestAnswer.kt
@@ -0,0 +1,40 @@
+package dev.inmo.tgbotapi.requests.chat.invite_links
+
+import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
+import dev.inmo.tgbotapi.types.*
+import kotlinx.serialization.*
+import kotlinx.serialization.builtins.serializer
+
+sealed interface ChatJoinRequestAnswer : SimpleRequest {
+ val chatId: ChatIdentifier
+ val userId: UserId
+
+ override val resultDeserializer: DeserializationStrategy
+ get() = Boolean.serializer()
+}
+
+@Serializable
+data class ApproveChatJoinRequest(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(userIdField)
+ override val userId: UserId
+) : ChatJoinRequestAnswer {
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+
+ override fun method(): String = "approveChatJoinRequest"
+}
+
+@Serializable
+data class DeclineChatJoinRequest(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(userIdField)
+ override val userId: UserId
+) : ChatJoinRequestAnswer {
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+
+ override fun method(): String = "declineChatJoinRequest"
+}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/CreateChatInviteLink.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/CreateChatInviteLink.kt
index 4a87ef49c7..79f9a00281 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/CreateChatInviteLink.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/CreateChatInviteLink.kt
@@ -1,31 +1,120 @@
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.abstracts.SimpleRequest
+import dev.inmo.tgbotapi.requests.chat.abstracts.*
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 {
+sealed interface CreateChatInviteLink : EditChatInviteLinkRequest {
+ val expirationUnixTimeStamp: TelegramDate?
override val expireDate: DateTime?
get() = expirationUnixTimeStamp ?.asDate
- override val requestSerializer: SerializationStrategy<*>
- get() = serializer()
-
override fun method(): String = "createChatInviteLink"
+
+ companion object {
+ fun unlimited(
+ chatId: ChatIdentifier,
+ name: String? = null,
+ expirationUnixTimeStamp: TelegramDate? = null,
+ ) = CreateChatInviteLinkUnlimited(chatId, name, expirationUnixTimeStamp)
+ fun withLimitedMembers(
+ chatId: ChatIdentifier,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expirationUnixTimeStamp: TelegramDate? = null,
+ ) = CreateChatInviteLinkWithLimitedMembers(chatId, membersLimit, name, expirationUnixTimeStamp)
+ fun withJoinRequest(
+ chatId: ChatIdentifier,
+ name: String? = null,
+ expirationUnixTimeStamp: TelegramDate? = null,
+ ) = CreateChatInviteLinkWithJoinRequest(chatId, name, expirationUnixTimeStamp)
+ fun unlimited(
+ chatId: ChatIdentifier,
+ expiration: DateTime,
+ name: String? = null,
+ ) = unlimited(chatId, name, expiration.toTelegramDate())
+ fun withLimitedMembers(
+ chatId: ChatIdentifier,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+ ) = withLimitedMembers(chatId, membersLimit, name, expiration.toTelegramDate())
+ fun withJoinRequest(
+ chatId: ChatIdentifier,
+ expiration: DateTime,
+ name: String? = null,
+ ) = withJoinRequest(chatId, name, expiration.toTelegramDate())
+ }
}
-fun CreateChatInviteLink(
- chatId: ChatId,
- expireDate: DateTime,
- membersLimit: MembersLimit? = null
-): CreateChatInviteLink = CreateChatInviteLink(
- chatId, expireDate.toTelegramDate(), membersLimit
-)
+/**
+ * Represent [https://core.telegram.org/bots/api#createchatinvitelink] request WITHOUT `member_limit`
+ * and `creates_join_request`
+ *
+ * @see CreateChatInviteLink.unlimited
+ * @see CreateChatInviteLinkWithLimitedMembers
+ * @see CreateChatInviteLinkWithJoinRequest
+ */
+@Serializable
+data class CreateChatInviteLinkUnlimited(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(expireDateField)
+ override val expirationUnixTimeStamp: TelegramDate? = null,
+) : CreateChatInviteLink {
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+ override val resultDeserializer: DeserializationStrategy
+ get() = ChatInviteLinkUnlimited.serializer()
+}
+
+/**
+ * Represent [https://core.telegram.org/bots/api#createchatinvitelink] request WITH `member_limit`
+ * and WITHOUT `creates_join_request`
+ *
+ * @see CreateChatInviteLink.withLimitedMembers
+ * @see CreateChatInviteLinkUnlimited
+ * @see CreateChatInviteLinkWithJoinRequest
+ */
+@Serializable
+data class CreateChatInviteLinkWithLimitedMembers(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(memberLimitField)
+ override val membersLimit: MembersLimit,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(expireDateField)
+ override val expirationUnixTimeStamp: TelegramDate? = null,
+) : CreateChatInviteLink, LimitedMembersChatInviteLinkRequest {
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+}
+
+/**
+ * Represent [https://core.telegram.org/bots/api#createchatinvitelink] request WITHOUT `member_limit`
+ * and WITH `creates_join_request`
+ *
+ * @see CreateChatInviteLink.withJoinRequest
+ * @see CreateChatInviteLinkUnlimited
+ * @see CreateChatInviteLinkWithLimitedMembers
+ */
+@Serializable
+data class CreateChatInviteLinkWithJoinRequest(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(expireDateField)
+ override val expirationUnixTimeStamp: TelegramDate? = null,
+) : CreateChatInviteLink, WithJoinRequestChatInviteLinkRequest {
+ @Required
+ @SerialName(createsJoinRequestField)
+ private val createsJoinRequest: Boolean = true
+
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/EditChatInviteLink.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/EditChatInviteLink.kt
index fdeb3b55e1..865dea0541 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/EditChatInviteLink.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/EditChatInviteLink.kt
@@ -1,35 +1,134 @@
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.requests.abstracts.SimpleRequest
+import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
+sealed interface EditChatInviteLink : EditChatInviteLinkRequest, KnownChatInviteLinkRequest {
+ val expirationUnixTimeStamp: TelegramDate?
+ override val expireDate: DateTime?
+ get() = expirationUnixTimeStamp ?.asDate
+ override fun method(): String = "editChatInviteLink"
+
+ companion object {
+ fun unlimited(
+ chatId: ChatIdentifier,
+ inviteLink: String,
+ name: String? = null,
+ expirationUnixTimeStamp: TelegramDate? = null,
+ ) = EditChatInviteLinkUnlimited(chatId, inviteLink, name, expirationUnixTimeStamp)
+ fun withLimitedMembers(
+ chatId: ChatIdentifier,
+ inviteLink: String,
+ membersLimit: MembersLimit,
+ name: String? = null,
+ expirationUnixTimeStamp: TelegramDate? = null,
+ ) = EditChatInviteLinkWithLimitedMembers(chatId, inviteLink, membersLimit, name, expirationUnixTimeStamp)
+ fun withJoinRequest(
+ chatId: ChatIdentifier,
+ inviteLink: String,
+ name: String? = null,
+ expirationUnixTimeStamp: TelegramDate? = null,
+ ) = EditChatInviteLinkWithJoinRequest(chatId, inviteLink, name, expirationUnixTimeStamp)
+ fun unlimited(
+ chatId: ChatIdentifier,
+ inviteLink: String,
+ expiration: DateTime,
+ name: String? = null,
+ ) = unlimited(chatId, inviteLink, name, expiration.toTelegramDate())
+ fun withLimitedMembers(
+ chatId: ChatIdentifier,
+ inviteLink: String,
+ membersLimit: MembersLimit,
+ expiration: DateTime,
+ name: String? = null,
+ ) = withLimitedMembers(chatId, inviteLink, membersLimit, name, expiration.toTelegramDate())
+ fun withJoinRequest(
+ chatId: ChatIdentifier,
+ inviteLink: String,
+ expiration: DateTime,
+ name: String? = null,
+ ) = withJoinRequest(chatId, inviteLink, name, expiration.toTelegramDate())
+ }
+}
+
+/**
+ * Represent [https://core.telegram.org/bots/api#editchatinvitelink] request WITHOUT `member_limit`
+ * and `creates_join_request`
+ *
+ * @see EditChatInviteLink.unlimited
+ * @see EditChatInviteLinkWithLimitedMembers
+ * @see EditChatInviteLinkWithJoinRequest
+ */
@Serializable
-data class EditChatInviteLink(
+data class EditChatInviteLinkUnlimited(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(inviteLinkField)
override val inviteLink: String,
+ @SerialName(nameField)
+ override val name: String? = null,
@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 expirationUnixTimeStamp: TelegramDate? = null,
+) : EditChatInviteLink {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
-
- override fun method(): String = "editChatInviteLink"
+ override val resultDeserializer: DeserializationStrategy
+ get() = ChatInviteLinkUnlimited.serializer()
}
-fun EditChatInviteLink(
- chatId: ChatIdentifier,
- inviteLink: String,
- expireDate: DateTime,
- membersLimit: MembersLimit? = null
-): EditChatInviteLink = EditChatInviteLink(
- chatId, inviteLink, expireDate.toTelegramDate(), membersLimit
-)
+/**
+ * Represent [https://core.telegram.org/bots/api#editchatinvitelink] request WITH `member_limit`
+ * and WITHOUT `creates_join_request`
+ *
+ * @see EditChatInviteLink.withLimitedMembers
+ * @see EditChatInviteLinkUnlimited
+ * @see EditChatInviteLinkWithJoinRequest
+ */
+@Serializable
+data class EditChatInviteLinkWithLimitedMembers(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(inviteLinkField)
+ override val inviteLink: String,
+ @SerialName(memberLimitField)
+ override val membersLimit: MembersLimit,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(expireDateField)
+ override val expirationUnixTimeStamp: TelegramDate? = null,
+) : EditChatInviteLink,
+ LimitedMembersChatInviteLinkRequest {
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+}
+
+/**
+ * Represent [https://core.telegram.org/bots/api#editchatinvitelink] request WITHOUT `member_limit`
+ * and WITH `creates_join_request`
+ *
+ * @see EditChatInviteLink.withJoinRequest
+ * @see EditChatInviteLinkUnlimited
+ * @see EditChatInviteLinkWithLimitedMembers
+ */
+@Serializable
+data class EditChatInviteLinkWithJoinRequest(
+ @SerialName(chatIdField)
+ override val chatId: ChatIdentifier,
+ @SerialName(inviteLinkField)
+ override val inviteLink: String,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(expireDateField)
+ override val expirationUnixTimeStamp: TelegramDate? = null,
+) : EditChatInviteLink,
+ WithJoinRequestChatInviteLinkRequest {
+ @Required
+ @SerialName(createsJoinRequestField)
+ private val createsJoinRequest: Boolean = true
+
+ override val requestSerializer: SerializationStrategy<*>
+ get() = serializer()
+}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/RevokeChatInviteLink.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/RevokeChatInviteLink.kt
index 31a8993666..fb6c77bf5a 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/RevokeChatInviteLink.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/chat/invite_links/RevokeChatInviteLink.kt
@@ -10,9 +10,11 @@ data class RevokeChatInviteLink(
override val chatId: ChatIdentifier,
@SerialName(inviteLinkField)
override val inviteLink: String
-) : KnownChatInviteLinkRequest {
+) : KnownChatInviteLinkRequest {
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
+ override val resultDeserializer: DeserializationStrategy
+ get() = SecondaryChatInviteLink.serializer()
override fun method(): String = "revokeChatInviteLink"
}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatInviteLink.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatInviteLink.kt
index e7771b2ad0..f6ea617990 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatInviteLink.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatInviteLink.kt
@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
+import dev.inmo.tgbotapi.CommonAbstracts.WithUser
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
@@ -17,10 +18,16 @@ private data class RawChatInviteLink(
val isPrimary: Boolean,
@SerialName(isRevokedField)
val isRevoked: Boolean,
+ @SerialName(nameField)
+ val name: String? = null,
@SerialName(expireDateField)
val expirationDateTime: TelegramDate? = null,
@SerialName(memberLimitField)
- val membersLimit: MembersLimit ?= null
+ val membersLimit: MembersLimit ?= null,
+ @SerialName(createsJoinRequestField)
+ val createsJoinRequest: Boolean? = null,
+ @SerialName(pendingJoinRequestCountField)
+ val pendingJoinRequestCount: MembersLimit ?= null
)
private fun ChatInviteLink.toRawChatInviteLink() = RawChatInviteLink(
@@ -28,18 +35,39 @@ private fun ChatInviteLink.toRawChatInviteLink() = RawChatInviteLink(
creator,
isPrimary,
isRevoked,
+ (this as? SecondaryChatInviteLink) ?.name,
expirationDateTime ?.toTelegramDate(),
- membersLimit
+ (this as? ChatInviteLinkWithLimitedMembers) ?.membersLimit,
+ this is ChatInviteLinkWithJoinRequest,
+ (this as? ChatInviteLinkWithJoinRequest) ?.leftToReview
)
@Serializable(ChatInviteLinkSerializer::class)
-sealed class ChatInviteLink {
- abstract val inviteLink: String
- abstract val creator: User
- abstract val isPrimary: Boolean
- abstract val isRevoked: Boolean
- abstract val expirationDateTime: DateTime?
- abstract val membersLimit: MembersLimit?
+sealed interface ChatInviteLink : WithUser {
+ val inviteLink: String
+ val creator: User
+ val isPrimary: Boolean
+ get() = this is PrimaryInviteLink
+ val isRevoked: Boolean
+ val expirationDateTime: DateTime?
+ val name: String?
+
+ override val user: User
+ get() = creator
+
+ companion object {
+ fun serializer(): KSerializer = ChatInviteLinkSerializer
+ }
+}
+
+@Serializable(ChatInviteLinkSerializer::class)
+sealed interface SecondaryChatInviteLink : ChatInviteLink {
+ override val isPrimary: Boolean
+ get() = false
+
+ companion object {
+ fun serializer(): KSerializer = ChatInviteLinkSerializer as KSerializer
+ }
}
@Serializable
@@ -52,30 +80,64 @@ data class PrimaryInviteLink(
override val isRevoked: Boolean = false,
@SerialName(expireDateField)
private val expireDate: TelegramDate? = null,
- @SerialName(memberLimitField)
- override val membersLimit: MembersLimit? = null
-) : ChatInviteLink() {
- override val isPrimary: Boolean
- get() = true
+) : ChatInviteLink {
+ override val expirationDateTime: DateTime?
+ get() = expireDate ?.asDate
+ override val name: String?
+ get() = null
+}
+
+@Serializable
+data class ChatInviteLinkWithJoinRequest(
+ @SerialName(inviteLinkField)
+ override val inviteLink: String,
+ @SerialName(creatorField)
+ override val creator: User,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(pendingJoinRequestCountField)
+ val leftToReview: Int = 0,
+ @SerialName(isRevokedField)
+ override val isRevoked: Boolean = false,
+ @SerialName(expireDateField)
+ private val expireDate: TelegramDate? = null
+) : SecondaryChatInviteLink {
override val expirationDateTime: DateTime?
get() = expireDate ?.asDate
}
@Serializable
-data class CommonInviteLink(
+data class ChatInviteLinkWithLimitedMembers(
@SerialName(inviteLinkField)
override val inviteLink: String,
@SerialName(creatorField)
override val creator: User,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(memberLimitField)
+ val membersLimit: MembersLimit,
@SerialName(isRevokedField)
override val isRevoked: Boolean = false,
@SerialName(expireDateField)
private val expireDate: TelegramDate? = null,
- @SerialName(memberLimitField)
- override val membersLimit: MembersLimit? = null
-) : ChatInviteLink() {
- override val isPrimary: Boolean
- get() = false
+) : SecondaryChatInviteLink {
+ override val expirationDateTime: DateTime?
+ get() = expireDate ?.asDate
+}
+
+@Serializable
+data class ChatInviteLinkUnlimited(
+ @SerialName(inviteLinkField)
+ override val inviteLink: String,
+ @SerialName(creatorField)
+ override val creator: User,
+ @SerialName(nameField)
+ override val name: String? = null,
+ @SerialName(isRevokedField)
+ override val isRevoked: Boolean = false,
+ @SerialName(expireDateField)
+ private val expireDate: TelegramDate? = null,
+) : SecondaryChatInviteLink {
override val expirationDateTime: DateTime?
get() = expireDate ?.asDate
}
@@ -89,11 +151,21 @@ object ChatInviteLinkSerializer : KSerializer {
val deserializedRaw = RawChatInviteLink.serializer().deserialize(decoder)
return deserializedRaw.run {
when {
- deserializedRaw.isPrimary -> PrimaryInviteLink(
- inviteLink, creator, isRevoked, expirationDateTime, membersLimit
+ isPrimary -> PrimaryInviteLink(
+ inviteLink, creator, isRevoked, expirationDateTime
)
- else -> CommonInviteLink(
- inviteLink, creator, isRevoked, expirationDateTime, membersLimit
+ createsJoinRequest == true -> {
+ ChatInviteLinkWithJoinRequest(
+ inviteLink, creator, name, pendingJoinRequestCount ?: 0, isRevoked, expirationDateTime
+ )
+ }
+ membersLimit != null -> {
+ ChatInviteLinkWithLimitedMembers(
+ inviteLink, creator, name, membersLimit, isRevoked, expirationDateTime
+ )
+ }
+ else -> ChatInviteLinkUnlimited(
+ inviteLink, creator, name, isRevoked, expirationDateTime
)
}
}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatJoinRequest.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatJoinRequest.kt
new file mode 100644
index 0000000000..05ca019dcc
--- /dev/null
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/ChatJoinRequest.kt
@@ -0,0 +1,20 @@
+package dev.inmo.tgbotapi.types
+
+import dev.inmo.tgbotapi.CommonAbstracts.FromUser
+import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ChatJoinRequest(
+ @SerialName(chatField)
+ val chat: PublicChat,
+ @SerialName(fromField)
+ override val from: User,
+ @SerialName(dateField)
+ val date: TelegramDate,
+ @SerialName(inviteLinkField)
+ val inviteLink: ChatInviteLink,
+ @SerialName(bioField)
+ val bio: String? = null
+) : FromUser
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt
index 8a9ba6d089..7d864b5820 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt
@@ -177,6 +177,8 @@ const val messageAutoDeleteTimeField = "message_auto_delete_time"
const val isPrimaryField = "is_primary"
const val isRevokedField = "is_revoked"
const val expireDateField = "expire_date"
+const val createsJoinRequestField = "creates_join_request"
+const val pendingJoinRequestCountField = "pending_join_request_count"
const val memberLimitField = "member_limit"
const val requestContactField = "request_contact"
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/UpdateTypes.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/UpdateTypes.kt
index 1606ea6ed4..913015c988 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/UpdateTypes.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/UpdateTypes.kt
@@ -13,6 +13,7 @@ const val UPDATE_POLL = "poll"
const val UPDATE_POLL_ANSWER = "poll_answer"
const val MY_CHAT_MEMBER = "my_chat_member"
const val CHAT_MEMBER = "chat_member"
+const val CHAT_JOIN_REQUEST = "chat_join_request"
val ALL_UPDATES_LIST = listOf(
UPDATE_MESSAGE,
@@ -27,5 +28,6 @@ val ALL_UPDATES_LIST = listOf(
UPDATE_POLL,
UPDATE_POLL_ANSWER,
MY_CHAT_MEMBER,
- CHAT_MEMBER
+ CHAT_MEMBER,
+ CHAT_JOIN_REQUEST
)
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/actions/BotAction.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/actions/BotAction.kt
index 8abad36be6..856f3d8899 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/actions/BotAction.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/actions/BotAction.kt
@@ -36,6 +36,7 @@ object BotActionSerializer: KSerializer {
FindLocationAction.actionName -> FindLocationAction
RecordVideoNoteAction.actionName -> RecordVideoNoteAction
UploadVideoNoteAction.actionName -> UploadVideoNoteAction
+ ChooseStickerAction.actionName -> ChooseStickerAction
else -> CustomBotAction(actionName)
}
}
@@ -151,6 +152,17 @@ inline val uploadVideoNote
get() = UploadVideoNoteAction
inline fun BotAction.asUploadVideoNote() = this as? UploadVideoNoteAction
+/**
+ * Will notify user that bot is uploading video note
+ */
+@Serializable(BotActionSerializer::class)
+object ChooseStickerAction : BotAction {
+ override val actionName: String = "choose_sticker"
+}
+inline val chooseSticker
+ get() = ChooseStickerAction
+inline fun BotAction.asChooseStickerAction() = this as? ChooseStickerAction
+
@Serializable(BotActionSerializer::class)
@Warning("Use this action only in case you are pretty sure that there are no other action for your needs")
class CustomBotAction @RiskFeature("Usage of this action may lead to errors") constructor(
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt
index e2693ae023..098e8c582a 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardButtons/InlineKeyboardButton.kt
@@ -26,10 +26,7 @@ data class UnknownInlineKeyboardButton internal constructor(
*/
@Serializable
data class PayInlineKeyboardButton(
- override val text: String,
- @Deprecated("Don't use this button due to removing of this in near release")
- @Transient
- val pay: Boolean = true
+ override val text: String
) : InlineKeyboardButton {
@ExperimentalSerializationApi
@EncodeDefault
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt
index e08dd2d4ba..e8c0db2a94 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt
@@ -20,7 +20,4 @@ data class PrivateContentMessageImpl(
override val replyTo: Message?,
override val replyMarkup: InlineKeyboardMarkup?,
override val senderBot: CommonBot?,
-) : PrivateContentMessage {
- @Deprecated("This value will always be null. You may get SuccessfulPayment as one of ChatEvents")
- val paymentInfo: SuccessfulPaymentEvent? = null
-}
+) : PrivateContentMessage
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt
index e981ab08a4..7fe6b71102 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt
@@ -4,8 +4,6 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent
import dev.inmo.tgbotapi.types.message.payments.abstracts.PaymentInfo
import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
-@Deprecated("Renamed", ReplaceWith("SuccessfulPaymentEvent", "dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent"))
-typealias SuccessfulPaymentInfo = SuccessfulPaymentEvent
data class SuccessfulPaymentEvent(
val payment: SuccessfulPayment
) : PaymentInfo, CommonEvent
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/ChatJoinRequestUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/ChatJoinRequestUpdate.kt
new file mode 100644
index 0000000000..2827be9ace
--- /dev/null
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/ChatJoinRequestUpdate.kt
@@ -0,0 +1,10 @@
+package dev.inmo.tgbotapi.types.update
+
+import dev.inmo.tgbotapi.types.ChatJoinRequest
+import dev.inmo.tgbotapi.types.UpdateIdentifier
+import dev.inmo.tgbotapi.types.update.abstracts.Update
+
+data class ChatJoinRequestUpdate(
+ override val updateId: UpdateIdentifier,
+ override val data: ChatJoinRequest
+) : Update
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/RawUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/RawUpdate.kt
index 87e46b45d3..bde9d23dd1 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/RawUpdate.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/RawUpdate.kt
@@ -35,7 +35,8 @@ internal data class RawUpdate constructor(
private val poll: Poll? = null,
private val poll_answer: PollAnswer? = null,
private val my_chat_member: ChatMemberUpdated? = null,
- private val chat_member: ChatMemberUpdated? = null
+ private val chat_member: ChatMemberUpdated? = null,
+ private val chat_join_request: ChatJoinRequest? = null
) {
private var initedUpdate: Update? = null
/**
@@ -61,6 +62,7 @@ internal data class RawUpdate constructor(
poll_answer != null -> PollAnswerUpdate(updateId, poll_answer)
my_chat_member != null -> MyChatMemberUpdatedUpdate(updateId, my_chat_member)
chat_member != null -> CommonChatMemberUpdatedUpdate(updateId, chat_member)
+ chat_join_request != null -> ChatJoinRequestUpdate(updateId, chat_join_request)
else -> UnknownUpdate(
updateId,
raw.toString(),
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt
index b37ceacb1c..db8de2ec2f 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt
@@ -32,6 +32,7 @@ interface FlowsUpdatesFilter : UpdatesFilter {
val pollAnswersFlow: Flow
val chatMemberUpdatesFlow: Flow
val myChatMemberUpdatesFlow: Flow
+ val chatJoinRequestUpdateFlow: Flow
val unknownUpdatesFlow: Flow
}
@@ -62,6 +63,7 @@ abstract class AbstractFlowsUpdatesFilter : FlowsUpdatesFilter {
override val pollAnswersFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() }
override val chatMemberUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() }
override val myChatMemberUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() }
+ override val chatJoinRequestUpdateFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() }
override val unknownUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() }
}
diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt
index 451b36d9a1..2f4e9cd6e7 100644
--- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt
+++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt
@@ -27,6 +27,7 @@ class BotActionTests {
FindLocationAction -> example.botAction.actionName
RecordVideoNoteAction -> example.botAction.actionName
UploadVideoNoteAction -> example.botAction.actionName
+ ChooseStickerAction -> example.botAction.actionName
is CustomBotAction -> example.botAction.actionName
}
)
@@ -56,7 +57,8 @@ class BotActionTests {
UploadDocumentAction.example(),
FindLocationAction.example(),
RecordVideoNoteAction.example(),
- UploadVideoNoteAction.example()
+ UploadVideoNoteAction.example(),
+ ChooseStickerAction.example(),
).forEach {
checkBotActionSerializeDeserialize(it)
}
diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt
index ae3d35a63c..d10233d1e5 100644
--- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt
+++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt
@@ -1274,6 +1274,15 @@ inline fun BotAction.asTypingAction(): TypingAction? = this as? TypingAction
@PreviewFeature
inline fun BotAction.requireTypingAction(): TypingAction = this as TypingAction
+@PreviewFeature
+inline fun BotAction.whenChooseStickerAction(block: (ChooseStickerAction) -> T) = asChooseStickerAction() ?.let(block)
+
+@PreviewFeature
+inline fun BotAction.asChooseStickerAction(): ChooseStickerAction? = this as? ChooseStickerAction
+
+@PreviewFeature
+inline fun BotAction.requireChooseStickerAction(): ChooseStickerAction = this as ChooseStickerAction
+
@PreviewFeature
inline fun BotAction.whenUploadVoiceAction(block: (UploadVoiceAction) -> T) = asUploadVoiceAction() ?.let(block)
@@ -2204,6 +2213,15 @@ inline fun Update.asChatMemberUpdatedUpdate(): ChatMemberUpdatedUpdate? = this a
@PreviewFeature
inline fun Update.requireChatMemberUpdatedUpdate(): ChatMemberUpdatedUpdate = this as ChatMemberUpdatedUpdate
+@PreviewFeature
+inline fun Update.whenChatJoinRequestUpdate(block: (ChatJoinRequestUpdate) -> T) = asChatJoinRequestUpdate() ?.let(block)
+
+@PreviewFeature
+inline fun Update.asChatJoinRequestUpdate(): ChatJoinRequestUpdate? = this as? ChatJoinRequestUpdate
+
+@PreviewFeature
+inline fun Update.requireChatJoinRequestUpdate(): ChatJoinRequestUpdate = this as ChatJoinRequestUpdate
+
@PreviewFeature
inline fun TelegramMediaFile.whenAnimationFile(block: (AnimationFile) -> T) = asAnimationFile() ?.let(block)
@@ -3188,3 +3206,48 @@ inline fun Location.asLiveLocation(): LiveLocation? = this as? LiveLocation
@PreviewFeature
inline fun Location.requireLiveLocation(): LiveLocation = this as LiveLocation
+
+@PreviewFeature
+inline fun ChatInviteLink.whenPrimaryInviteLink(block: (PrimaryInviteLink) -> T) = asPrimaryInviteLink() ?.let(block)
+
+@PreviewFeature
+inline fun ChatInviteLink.asPrimaryInviteLink(): PrimaryInviteLink? = this as? PrimaryInviteLink
+
+@PreviewFeature
+inline fun ChatInviteLink.requirePrimaryInviteLink(): PrimaryInviteLink = this as PrimaryInviteLink
+
+@PreviewFeature
+inline fun ChatInviteLink.whenSecondaryChatInviteLink(block: (SecondaryChatInviteLink) -> T) = asSecondaryChatInviteLink() ?.let(block)
+
+@PreviewFeature
+inline fun ChatInviteLink.asSecondaryChatInviteLink(): SecondaryChatInviteLink? = this as? SecondaryChatInviteLink
+
+@PreviewFeature
+inline fun ChatInviteLink.requireSecondaryChatInviteLink(): SecondaryChatInviteLink = this as SecondaryChatInviteLink
+
+@PreviewFeature
+inline fun ChatInviteLink.whenChatInviteLinkWithJoinRequest(block: (ChatInviteLinkWithJoinRequest) -> T) = asChatInviteLinkWithJoinRequest() ?.let(block)
+
+@PreviewFeature
+inline fun ChatInviteLink.asChatInviteLinkWithJoinRequest(): ChatInviteLinkWithJoinRequest? = this as? ChatInviteLinkWithJoinRequest
+
+@PreviewFeature
+inline fun ChatInviteLink.requireChatInviteLinkWithJoinRequest(): ChatInviteLinkWithJoinRequest = this as ChatInviteLinkWithJoinRequest
+
+@PreviewFeature
+inline fun ChatInviteLink.whenChatInviteLinkWithLimitedMembers(block: (ChatInviteLinkWithLimitedMembers) -> T) = asChatInviteLinkWithLimitedMembers() ?.let(block)
+
+@PreviewFeature
+inline fun ChatInviteLink.asChatInviteLinkWithLimitedMembers(): ChatInviteLinkWithLimitedMembers? = this as? ChatInviteLinkWithLimitedMembers
+
+@PreviewFeature
+inline fun ChatInviteLink.requireChatInviteLinkWithLimitedMembers(): ChatInviteLinkWithLimitedMembers = this as ChatInviteLinkWithLimitedMembers
+
+@PreviewFeature
+inline fun ChatInviteLink.whenChatInviteLinkUnlimited(block: (ChatInviteLinkUnlimited) -> T) = asChatInviteLinkUnlimited() ?.let(block)
+
+@PreviewFeature
+inline fun ChatInviteLink.asChatInviteLinkUnlimited(): ChatInviteLinkUnlimited? = this as? ChatInviteLinkUnlimited
+
+@PreviewFeature
+inline fun ChatInviteLink.requireChatInviteLinkUnlimited(): ChatInviteLinkUnlimited = this as ChatInviteLinkUnlimited
diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt
index 9507f7052b..4ce905c52f 100644
--- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt
+++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt
@@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.CommonAbstracts.WithUser
import dev.inmo.tgbotapi.extensions.utils.asFromUser
import dev.inmo.tgbotapi.extensions.utils.asUser
import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
+import dev.inmo.tgbotapi.types.ChatJoinRequest
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.update.*
@@ -14,12 +15,13 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.PreviewFeature
@PreviewFeature
-fun Update.sourceChat(): Chat? = when {
- this is MediaGroupUpdate -> when (this) {
+fun Update.sourceChat(): Chat? = when (this) {
+ is MediaGroupUpdate -> when (this) {
is SentMediaGroupUpdate -> data.chat
is EditMediaGroupUpdate -> data.chat
}
- this is BaseMessageUpdate -> data.chat
+ is BaseMessageUpdate -> data.chat
+ is ChatJoinRequestUpdate -> data.chat
else -> {
when (val data = data) {
is FromUser -> data.from