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

Compare commits

...

27 Commits

Author SHA1 Message Date
ffbe8fc5e0 Update libs.versions.toml 2023-05-31 01:20:07 +06:00
610ed95296 Update CHANGELOG.md 2023-05-30 14:15:10 +06:00
d3f4a895ff Update libs.versions.toml 2023-05-30 14:14:39 +06:00
51c7c376d7 all previous deprecations have been removed 2023-05-28 20:39:46 +06:00
393197eca1 fixes 2023-05-27 18:33:28 +06:00
67096f8e0e update dependencies 2023-05-27 18:19:14 +06:00
c312a05d6b start 8.0.0 2023-05-27 18:10:52 +06:00
b575695f90 Merge pull request #753 from InsanusMokrassar/7.1.3
7.1.3
2023-05-19 22:50:22 +06:00
65bcf83517 update ClassCasts 2023-05-19 22:42:42 +06:00
f07a179448 InputFile kdocs improvements 2023-05-18 13:06:41 +06:00
ed2c447730 fix of #645 2023-05-18 12:59:35 +06:00
cb4c48d025 waitMediaContent/waitMediaContentMessage/onMediaContent 2023-05-18 11:45:27 +06:00
1a21fa85ac fixes 2023-05-18 11:39:47 +06:00
191fa5406d start 7.1.3 2023-05-11 20:45:24 +06:00
6959dacfc4 Merge pull request #752 from InsanusMokrassar/7.1.2
7.1.2
2023-05-06 13:28:42 +06:00
ced11ab336 downgrade microutils and revert coroutines 2023-05-06 13:25:27 +06:00
6686aef4fa update dependencies in preview mode 2023-05-06 12:25:24 +06:00
9ede545e56 add serialization of Stickers 2023-05-06 12:00:08 +06:00
a74066cf62 start 7.1.2 2023-05-06 11:38:05 +06:00
0a7e99bbb3 Merge pull request #750 from InsanusMokrassar/7.1.1
7.1.1
2023-05-02 01:48:06 +06:00
913f584469 update kotlin poet 2023-05-01 02:15:27 +06:00
20278804bf potential fix of exception printing on skipping of timeout exceptions 2023-05-01 01:52:24 +06:00
631f1b9427 start 7.1.1, update dependencies and add fixes in makeLinkToMessage 2023-04-30 21:00:27 +06:00
5e0106beb5 Update README.md 2023-04-29 11:19:06 +06:00
d37e01f93e Merge pull request #748 from InsanusMokrassar/renovate/ksp
Update ksp to v1.8.21-1.0.11
2023-04-28 00:05:28 +06:00
renovate[bot]
d4492ec7ac Update ksp to v1.8.21-1.0.11 2023-04-27 17:42:32 +00:00
60d24259f4 Merge pull request #747 from InsanusMokrassar/7.1.0
7.1.0
2023-04-22 11:08:29 +06:00
59 changed files with 921 additions and 268 deletions

View File

@@ -1,5 +1,48 @@
# TelegramBotAPI changelog
## 8.0.0
**THIS UPDATE CONTAINS BREAKING CHANGES**
**ALL PROJECT DEPRECATIONS HAVE BEEN REMOVED**
**IN THIS UPDATE KORLIBS HAVE BEEN UPDATED TO VERSION `4.0.2`. SINCE THAT VERSION A LOT OF PACKAGES HAVE BEEN RENAMED.
MIGRATIONS USED IN THIS LIB:**
* `com.soywiz.klock` -> `korlibs.time`
* `com.soywiz.krypto` -> `korlibs.crypto`
* `Versions`:
* `Korlibs`: `3.4.0` -> `4.0.3`
* `MicroUtils`: `0.18.4` -> `0.19.1`
## 7.1.3
* `Versions`:
* `Serialization`: `1.5.0` -> `1.5.1`
* `MicroUtils`: `0.18.1` -> `0.18.4`
* `Core`:
* Actualize kdocs in `InputFile`
* `BehaviourBuilder`:
* Now it is possible to use `waitMediaContent`/`waitMediaContentMessage`/`onMediaContent`
* Add `onMention`/`waitMention` functionality
* Add opportunity to map content with extensions to `Flow`
## 7.1.2
* `Versions`:
* `MicroUtils`: `0.18.0` -> `0.18.1`
* `Core`:
* Now it is possible to serialize `Sticker`s
## 7.1.1
* `Versions`:
* `Kotlin`: `1.8.20` -> `1.8.21`
* `MicroUtils`: `0.17.8` -> `0.18.0`
* `Utils`:
* Fixes in `makeLinkToMessage`
## 7.1.0
**This update contains changes according to the [Telegram Bot API 6.7](https://core.telegram.org/bots/api-changelog#april-21-2023)**

View File

@@ -5,7 +5,7 @@
| Useful repos | [![Create bot](https://img.shields.io/static/v1?label=Github&message=Template&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![Examples](https://img.shields.io/static/v1?label=Github&message=Examples&color=blue&logo=github)](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/) |
| Misc | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Small survey](https://img.shields.io/static/v1?label=Google&message=Survey&color=blue&logo=google-sheets)](https://docs.google.com/forms/d/e/1FAIpQLSctdJHT_aEniyYT0-IUAEfo1hsIlezX2owlkEAYX4KPl2V2_A/viewform?usp=sf_link) |
| Platforms | ![JVM](https://img.shields.io/badge/JVM-red?style=plastic&logo=openjdk&logoColor=white) ![Js](https://img.shields.io/badge/JavaScript-323330?style=plastic&logo=javascript&logoColor=F7DF1E) |
| Experimental Platforms | ![Linux x64](https://img.shields.io/badge/LinuxX64-FCC624?style=plastic&logo=linux&logoColor=black) ![MinGW x64](https://img.shields.io/badge/MinGWX64-black?style=plastic&logo=windows&logoColor=green) |
| Experimental Platforms | [![Linux x64](https://img.shields.io/badge/LinuxX64-FCC624?style=plastic&logo=linux&logoColor=black)](https://kotlinlang.org/docs/native-target-support.html#tier-1) [![MinGW x64](https://img.shields.io/badge/MinGWX64-black?style=plastic&logo=windows&logoColor=green)](https://kotlinlang.org/docs/native-target-support.html#tier-1) |
<!--- [![Telegram Channel](./resources/tg_channel_qr.jpg)](https://t.me/ktgbotapi) --->

View File

@@ -6,4 +6,4 @@ kotlin.incremental=true
kotlin.incremental.js=true
library_group=dev.inmo
library_version=7.1.0
library_version=8.0.0

View File

@@ -1,19 +1,19 @@
[versions]
kotlin = "1.8.20"
kotlin-serialization = "1.5.0"
kotlin = "1.8.21"
kotlin-serialization = "1.5.1"
kotlin-coroutines = "1.6.4"
javax-activation = "1.1.1"
korlibs = "3.4.0"
korlibs = "4.0.3"
uuid = "0.7.0"
ktor = "2.3.0"
ksp = "1.8.20-1.0.11"
kotlin-poet = "1.13.0"
ksp = "1.8.21-1.0.11"
kotlin-poet = "1.14.2"
microutils = "0.17.8"
microutils = "0.19.1"
github-release-plugin = "2.4.1"
dokka = "1.8.10"

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.extensions.api
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import korlibs.time.DateTime
import korlibs.time.TimeSpan
import dev.inmo.micro_utils.coroutines.LinkedSupervisorJob
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.CreateChatInviteLink
import dev.inmo.tgbotapi.types.ChatIdentifier

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.chat.invite_links.EditChatInviteLink
import dev.inmo.tgbotapi.types.ChatIdentifier

View File

@@ -15,14 +15,3 @@ suspend fun TelegramBot.editMessageMedia(
media: TelegramMedia,
replyMarkup: InlineKeyboardMarkup? = null
) = execute(EditInlineMessageMedia(inlineMessageId, media, replyMarkup))
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
@Deprecated("Renamed", ReplaceWith("this.editMessageMedia(inlineMessageId, media, replyMarkup)", "dev.inmo.tgbotapi.extensions.api.edit.media.editMessageMedia"))
suspend fun TelegramBot.editMessageCaption(
inlineMessageId: InlineMessageIdentifier,
media: TelegramMedia,
replyMarkup: InlineKeyboardMarkup? = null
) = execute(EditInlineMessageMedia(inlineMessageId, media, replyMarkup))

View File

@@ -72,76 +72,3 @@ suspend fun TelegramBot.setStickerSetThumbnail(
) = setStickerSetThumbnail(
user.id, stickerSet.name, thumbnail
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSetName: String,
thumb: FileId
) = execute(
SetStickerSetThumbnail(userId, thumbSetName, thumb)
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSetName: String,
thumb: MultipartFile
) = execute(
SetStickerSetThumbnail(userId, thumbSetName, thumb)
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSetName: String,
thumb: FileId
) = setStickerSetThumb(
user.id, thumbSetName, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSetName, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSetName: String,
thumb: MultipartFile
) = setStickerSetThumb(
user.id, thumbSetName, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSet: StickerSet,
thumb: FileId
) = setStickerSetThumb(
userId, thumbSet.name, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(userId, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
userId: UserId,
thumbSet: StickerSet,
thumb: MultipartFile
) = setStickerSetThumb(
userId, thumbSet.name, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSet: StickerSet,
thumb: FileId
) = setStickerSetThumb(
user.id, thumbSet.name, thumb
)
@Deprecated("Renamed in telegram bot api", ReplaceWith("setStickerSetThumbnail(user, thumbSet, thumb)", "dev.inmo.tgbotapi.extensions.api.thumbs.setStickerSetThumbnail"))
suspend fun TelegramBot.setStickerSetThumb(
user: CommonUser,
thumbSet: StickerSet,
thumb: MultipartFile
) = setStickerSetThumb(
user.id, thumbSet.name, thumb
)

View File

@@ -10,117 +10,127 @@ import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
@RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContent(
suspend inline fun BehaviourContext.waitContent(
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<O> = waitContentMessage<O>(initRequest, errorFactory).map { it.content }
): Flow<MessageContent> = waitContentMessage(initRequest, errorFactory).map { it.content }
inline fun <reified T : MessageContent> Flow<MessageContent>.mapContent() = mapNotNull { it as? T }
suspend fun BehaviourContext.waitAnyContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<MessageContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory)
suspend fun BehaviourContext.waitTextedContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<TextedContent>()
suspend fun BehaviourContext.waitContact(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<ContactContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<ContactContent>()
suspend fun BehaviourContext.waitDice(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<DiceContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<DiceContent>()
suspend fun BehaviourContext.waitGame(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<GameContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<GameContent>()
suspend fun BehaviourContext.waitLocation(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<LocationContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<LocationContent>()
suspend fun BehaviourContext.waitLiveLocation(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<LiveLocationContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<LiveLocationContent>()
suspend fun BehaviourContext.waitStaticLocation(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<StaticLocationContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<StaticLocationContent>()
suspend fun BehaviourContext.waitPoll(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<PollContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<PollContent>()
suspend fun BehaviourContext.waitText(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<TextContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<TextContent>()
suspend fun BehaviourContext.waitVenue(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<VenueContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<VenueContent>()
suspend fun BehaviourContext.waitAudioMediaGroupContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<AudioMediaGroupPartContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<AudioMediaGroupPartContent>()
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<DocumentMediaGroupPartContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<DocumentMediaGroupPartContent>()
suspend fun BehaviourContext.waitMedia(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<MediaContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<MediaContent>()
suspend fun BehaviourContext.waitAnyMediaGroupContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<MediaGroupPartContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<MediaGroupPartContent>()
suspend fun BehaviourContext.waitVisualMediaGroupContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<VisualMediaGroupPartContent>()
suspend fun BehaviourContext.waitTextedMediaContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<TextedMediaContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<TextedMediaContent>()
suspend fun BehaviourContext.waitAnimation(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<AnimationContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<AnimationContent>()
suspend fun BehaviourContext.waitAudio(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<AudioContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<AudioContent>()
suspend fun BehaviourContext.waitDocument(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<DocumentContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<DocumentContent>()
suspend fun BehaviourContext.waitPhoto(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContent<PhotoContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<PhotoContent>()
suspend fun BehaviourContext.waitSticker(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<StickerContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<StickerContent>()
suspend fun BehaviourContext.waitVideo(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<VideoContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<VideoContent>()
suspend fun BehaviourContext.waitVideoNote(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<VideoNoteContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<VideoNoteContent>()
suspend fun BehaviourContext.waitVoice(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<VoiceContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<VoiceContent>()
suspend fun BehaviourContext.waitInvoice(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<InvoiceContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<InvoiceContent>()
suspend fun BehaviourContext.waitVisualContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
) = waitContent(initRequest, errorFactory).mapContent<VisualMediaGroupPartContent>()
suspend fun BehaviourContext.waitMediaContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<MediaContent>()

View File

@@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.*
@@ -12,142 +13,138 @@ import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.mapNotNull
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
@RiskFeature(lowLevelRiskFeatureMessage)
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContentMessage(
suspend inline fun BehaviourContext.waitContentMessage(
initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<CommonMessage<O>> = expectFlow(
): Flow<CommonMessage<MessageContent>> = expectFlow(
initRequest,
errorFactory
) {
if (it !is BaseSentMessageUpdate) {
return@expectFlow emptyList()
}
listOfNotNull((it.data as? CommonMessage<*>) ?.withContent<O>())
listOfNotNull((it.data as? CommonMessage<*>))
}
internal inline fun <reified T : MessageContent> contentMessageConverter(
noinline mapper: CommonMessageToCommonMessageMapper<T>? = null
): suspend CommonMessage<MessageContent>.() -> CommonMessage<T>? = mapper ?.let {
{
if (content is T) {
@Suppress("UNCHECKED_CAST")
val message = (this as CommonMessage<T>)
safelyWithoutExceptions { mapper(message) }
} else {
null
}
}
} ?: {
@Suppress("UNCHECKED_CAST")
if (content is T) this as CommonMessage<T> else null
}
inline fun <reified T : MessageContent> Flow<CommonMessage<MessageContent>>.mapWithContent() = mapNotNull { it.withContentOrNull<T>() }
suspend fun BehaviourContext.waitAnyContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContentMessage<MessageContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory)
suspend fun BehaviourContext.waitTextedContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null },
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedContent>()
suspend fun BehaviourContext.waitContactMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<ContactContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<ContactContent>()
suspend fun BehaviourContext.waitDiceMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<DiceContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DiceContent>()
suspend fun BehaviourContext.waitGameMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<GameContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<GameContent>()
suspend fun BehaviourContext.waitLocationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<LocationContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<LocationContent>()
suspend fun BehaviourContext.waitLiveLocationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<LiveLocationContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<LiveLocationContent>()
suspend fun BehaviourContext.waitStaticLocationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<StaticLocationContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StaticLocationContent>()
suspend fun BehaviourContext.waitPollMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<PollContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<PollContent>()
suspend fun BehaviourContext.waitTextMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<TextContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextContent>()
suspend fun BehaviourContext.waitVenueMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<VenueContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VenueContent>()
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<AudioMediaGroupPartContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AudioMediaGroupPartContent>()
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<DocumentMediaGroupPartContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DocumentMediaGroupPartContent>()
suspend fun BehaviourContext.waitMediaMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<MediaContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaContent>()
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<MediaGroupPartContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaGroupPartContent>()
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VisualMediaGroupPartContent>()
suspend fun BehaviourContext.waitTextedMediaContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<TextedMediaContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedMediaContent>()
suspend fun BehaviourContext.waitAnimationMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<AnimationContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AnimationContent>()
suspend fun BehaviourContext.waitAudioMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<AudioContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<AudioContent>()
suspend fun BehaviourContext.waitDocumentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<DocumentContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<DocumentContent>()
suspend fun BehaviourContext.waitPhotoMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<PhotoContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<PhotoContent>()
suspend fun BehaviourContext.waitStickerMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<StickerContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StickerContent>()
suspend fun BehaviourContext.waitVideoMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<VideoContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VideoContent>()
suspend fun BehaviourContext.waitVideoNoteMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<VideoNoteContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VideoNoteContent>()
suspend fun BehaviourContext.waitVoiceMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<VoiceContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VoiceContent>()
suspend fun BehaviourContext.waitInvoiceMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<InvoiceContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<InvoiceContent>()
suspend fun BehaviourContext.waitVisualContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
) = waitContentMessage(initRequest, errorFactory).mapWithContent<VisualMediaGroupPartContent>()
suspend fun BehaviourContext.waitMediaContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaContent>()

View File

@@ -0,0 +1,107 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.whenMentionTextSource
import dev.inmo.tgbotapi.extensions.utils.whenTextMentionTextSource
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.Username
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.MessageContent
import dev.inmo.tgbotapi.types.message.content.TextedContent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
/**
* Check, that [TextedContent.textSources] contains:
*
* * Any [dev.inmo.tgbotapi.types.message.textsources.MentionTextSource] with [dev.inmo.tgbotapi.types.message.textsources.MentionTextSource.username]
* equal to [username]
* * Any [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource] with [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource.user]
* with the same [username]
*/
fun TextedContent.isWithMention(username: Username) = textSources.any {
it.whenMentionTextSource {
it.username == username
} ?: it.whenTextMentionTextSource {
it.user.username == username
} ?: false
}
/**
* Check, that [TextedContent.textSources] contains:
*
* * Any [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource] with [dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource.user]
* with the same [userId]
*/
fun TextedContent.isWithTextMention(userId: UserId) = textSources.any {
it.whenTextMentionTextSource {
it.user.id == userId
} ?: false
}
/**
* Uses [isWithMention] with [user] [Username] (is presented) or [isWithTextMention] with [user] [UserId] to determine
* user mentioning in [this] [CommonMessage]
*/
fun TextedContent.isWithMention(user: User): Boolean = user.username ?.let { username -> isWithMention(username) } == true || isWithTextMention(user.id)
/**
* Uses [isWithMention] passing [username] as argument to take only messages with [username] mentions or text mentions
*/
fun Flow<TextedContent>.filterMentions(username: Username) = filter {
it.isWithMention(username)
}
/**
* Uses [isWithTextMention] passing [userId] as argument to take only messages with [userId] text mentions
*/
fun Flow<TextedContent>.filterTextMentions(userId: UserId) = filter {
it.isWithTextMention(userId)
}
/**
* Uses [isWithMention] passing [user] as argument to take only messages with [user] mentions or text mentions
*/
fun Flow<TextedContent>.filterMentions(user: User) = filter {
it.isWithMention(user)
}
/**
* Creates cold [Flow] with the messages with [TextedContent] where [username] has been mentioned
*
* @see filterMentions
* @see filterTextMentions
*/
suspend fun BehaviourContext.waitContentWithMentions (
username: Username,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<TextedContent>().filterMentions(username)
/**
* Creates cold [Flow] with the messages with [TextedContent] where [userId] has been mentioned with text
*
* @see filterTextMentions
* @see filterMentions
* @see dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource
*/
suspend fun BehaviourContext.waitContentWithTextMentions (
userId: UserId,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitTextedContent(initRequest, errorFactory).filterTextMentions(userId)
/**
* Creates cold [Flow] with the messages with [TextedContent] where [user] has been mentioned as text or mentioned
* with text
*
* @see filterMentions
* @see filterTextMentions
*/
suspend fun BehaviourContext.waitContentWithMentions (
user: User,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitTextedContent(initRequest, errorFactory).filterMentions(user)

View File

@@ -0,0 +1,82 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.whenMentionTextSource
import dev.inmo.tgbotapi.extensions.utils.whenTextMentionTextSource
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.Username
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.TextedContent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
fun CommonMessage<TextedContent>.isWithMention(username: Username) = content.isWithMention(username)
fun CommonMessage<TextedContent>.isWithTextMention(userId: UserId) = content.isWithTextMention(userId)
/**
* Uses [isWithMention] with [user] [Username] (is presented) or [isWithTextMention] with [user] [UserId] to determine
* user mentioning in [this] [CommonMessage]
*/
fun CommonMessage<TextedContent>.isWithMention(user: User): Boolean = content.isWithMention(user)
/**
* Uses [isWithMention] passing [username] as argument to take only messages with [username] mentions or text mentions
*/
fun Flow<CommonMessage<TextedContent>>.filterMentionsMessages(username: Username) = filter {
it.isWithMention(username)
}
/**
* Uses [isWithTextMention] passing [userId] as argument to take only messages with [userId] text mentions
*/
fun Flow<CommonMessage<TextedContent>>.filterTextMentionsMessages(userId: UserId) = filter {
it.isWithTextMention(userId)
}
/**
* Uses [isWithMention] passing [user] as argument to take only messages with [user] mentions or text mentions
*/
fun Flow<CommonMessage<TextedContent>>.filterMentionsMessages(user: User) = filter {
it.isWithMention(user)
}
/**
* Creates cold [Flow] with the messages with [TextedContent] where [username] has been mentioned
*
* @see filterMentions
* @see filterTextMentions
*/
suspend fun BehaviourContext.waitContentMessageWithMentions (
username: Username,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage(initRequest, errorFactory).mapWithContent<TextedContent>().filterMentionsMessages(username)
/**
* Creates cold [Flow] with the messages with [TextedContent] where [userId] has been mentioned with text
*
* @see filterTextMentions
* @see filterMentions
* @see dev.inmo.tgbotapi.types.message.textsources.TextMentionTextSource
*/
suspend fun BehaviourContext.waitContentMessageWithTextMentions (
userId: UserId,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitTextedContentMessage(initRequest, errorFactory).filterTextMentionsMessages(userId)
/**
* Creates cold [Flow] with the messages with [TextedContent] where [user] has been mentioned as text or mentioned
* with text
*
* @see filterMentions
* @see filterTextMentions
*/
suspend fun BehaviourContext.waitContentMessageWithMentions (
user: User,
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitTextedContentMessage(initRequest, errorFactory).filterMentionsMessages(user)

View File

@@ -248,6 +248,30 @@ suspend fun <BC : BehaviourContext> BC.onText(
scenarioReceiver
)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onTextedContent(
initialFilter: CommonMessageFilter<TextedContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextedMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in TextedMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, TextedMessage>
) = onContentMessageWithType(
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,
@@ -631,3 +655,27 @@ suspend fun <BC : BehaviourContext> BC.onVisualContent(
markerFactory,
scenarioReceiver
)
/**
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
* to combinate several filters
* @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onMediaContent(
initialFilter: CommonMessageFilter<MediaContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, MediaMessage, Update> = MessageFilterByChat,
markerFactory: MarkerFactory<in MediaMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, MediaMessage>
) = onContentMessageWithType(
initialFilter,
subcontextUpdatesFilter,
markerFactory,
scenarioReceiver
)

View File

@@ -0,0 +1,357 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTwoTypesReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTypeReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.isWithMention
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.isWithTextMention
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.AnyMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.Username
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.AnimationContent
import dev.inmo.tgbotapi.types.message.content.AudioContent
import dev.inmo.tgbotapi.types.message.content.DocumentContent
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
import dev.inmo.tgbotapi.types.message.content.PhotoContent
import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextedContent
import dev.inmo.tgbotapi.types.message.content.VideoContent
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent
import dev.inmo.tgbotapi.types.message.content.VoiceContent
import dev.inmo.tgbotapi.types.update.abstracts.Update
internal suspend inline fun <BC : BehaviourContext, reified T : TextedContent> BC.onMention(
username: Username,
initialFilter: CommonMessageFilter<T>? = null,
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = AnyMarkerFactory(),
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
) = onContentMessageWithType<BC, T>(
initialFilter * {
it.content.isWithMention(username)
},
subcontextUpdatesFilter,
markerFactory,
scenarioReceiver
)
internal suspend inline fun <BC : BehaviourContext, reified T : TextedContent> BC.onTextMention(
userId: UserId,
initialFilter: CommonMessageFilter<T>? = null,
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = AnyMarkerFactory(),
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
) = onContentMessageWithType<BC, T>(
initialFilter * {
it.content.isWithTextMention(userId)
},
subcontextUpdatesFilter,
markerFactory,
scenarioReceiver
)
internal suspend inline fun <BC : BehaviourContext, reified T : TextedContent> BC.onMention(
user: User,
initialFilter: CommonMessageFilter<T>? = null,
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<T>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<T>, Any> = AnyMarkerFactory(),
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<T>>
) = onContentMessageWithType<BC, T>(
initialFilter * {
it.content.isWithMention(user)
},
subcontextUpdatesFilter,
markerFactory,
scenarioReceiver
)
suspend fun <BC : BehaviourContext> BC.onMentionWithAnyContent(
username: Username,
initialFilter: CommonMessageFilter<TextedContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<TextedContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithAnyContent(
userId: UserId,
initialFilter: CommonMessageFilter<TextedContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<TextedContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithAnyContent(
user: User,
initialFilter: CommonMessageFilter<TextedContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextedContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<TextedContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextedContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithVoiceContent(
username: Username,
initialFilter: CommonMessageFilter<VoiceContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithVoiceContent(
userId: UserId,
initialFilter: CommonMessageFilter<VoiceContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithVoiceContent(
user: User,
initialFilter: CommonMessageFilter<VoiceContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VoiceContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VoiceContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VoiceContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupContent(
username: Username,
initialFilter: CommonMessageFilter<MediaGroupContent<MediaGroupPartContent>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupContent<MediaGroupPartContent>>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithMediaGroupContent(
userId: UserId,
initialFilter: CommonMessageFilter<MediaGroupContent<MediaGroupPartContent>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupContent<MediaGroupPartContent>>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupContent(
user: User,
initialFilter: CommonMessageFilter<MediaGroupContent<MediaGroupPartContent>>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<MediaGroupContent<MediaGroupPartContent>>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupContent<MediaGroupPartContent>>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupPartContent(
username: Username,
initialFilter: CommonMessageFilter<MediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupPartContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupPartContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithMediaGroupPartContent(
userId: UserId,
initialFilter: CommonMessageFilter<MediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupPartContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupPartContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithMediaGroupPartContent(
user: User,
initialFilter: CommonMessageFilter<MediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<MediaGroupPartContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<MediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<MediaGroupPartContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithAudioContent(
username: Username,
initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithAudioContent(
userId: UserId,
initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithAudioContent(
user: User,
initialFilter: CommonMessageFilter<AudioContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AudioContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<AudioContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AudioContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithDocumentContent(
username: Username,
initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithDocumentContent(
userId: UserId,
initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithDocumentContent(
user: User,
initialFilter: CommonMessageFilter<DocumentContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<DocumentContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<DocumentContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<DocumentContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithVisualMediaGroupPartContent(
username: Username,
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VisualMediaGroupPartContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VisualMediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VisualMediaGroupPartContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithVisualMediaGroupPartContent(
userId: UserId,
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VisualMediaGroupPartContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VisualMediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VisualMediaGroupPartContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithVisualMediaGroupPartContent(
user: User,
initialFilter: CommonMessageFilter<VisualMediaGroupPartContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VisualMediaGroupPartContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VisualMediaGroupPartContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VisualMediaGroupPartContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithVideoContent(
username: Username,
initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithVideoContent(
userId: UserId,
initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithVideoContent(
user: User,
initialFilter: CommonMessageFilter<VideoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<VideoContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<VideoContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<VideoContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithPhotoContent(
username: Username,
initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithPhotoContent(
userId: UserId,
initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithPhotoContent(
user: User,
initialFilter: CommonMessageFilter<PhotoContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<PhotoContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<PhotoContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<PhotoContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithAnimationContent(
username: Username,
initialFilter: CommonMessageFilter<AnimationContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithAnimationContent(
userId: UserId,
initialFilter: CommonMessageFilter<AnimationContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithAnimationContent(
user: User,
initialFilter: CommonMessageFilter<AnimationContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<AnimationContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<AnimationContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<AnimationContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithTextContent(
username: Username,
initialFilter: CommonMessageFilter<TextContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
) = onMention(username, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onTextMentionWithTextContent(
userId: UserId,
initialFilter: CommonMessageFilter<TextContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
) = onTextMention(userId, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
suspend fun <BC : BehaviourContext> BC.onMentionWithTextContent(
user: User,
initialFilter: CommonMessageFilter<TextContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, CommonMessage<TextContent>, Update>? = null,
markerFactory: MarkerFactory<in CommonMessage<TextContent>, Any> = AnyMarkerFactory(),
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, CommonMessage<TextContent>>
) = onMention(user, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)

View File

@@ -5,5 +5,3 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
interface WithReplyMarkup {
val replyMarkup: KeyboardMarkup?
}
@Deprecated("Renamed", ReplaceWith("WithReplyMarkup", "dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup"))
typealias ReplyMarkup = WithReplyMarkup

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.bot.exceptions
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.types.RetryAfterError
import io.ktor.utils.io.errors.IOException

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.bot.settings.limiters
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MilliSeconds
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Semaphore
@@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlin.math.roundToLong
private fun now(): Long = DateTime.nowUnixLong()
private fun now(): Long = DateTime.nowUnixMillisLong()
@Serializable
class CommonLimiter(

View File

@@ -14,7 +14,6 @@ object ExceptionsOnlyLimiter : RequestLimiter {
result = runCatchingSafely {
block()
}.onFailure {
it.printStackTrace()
if (it is TooMuchRequestsException) {
delay(it.retryAfter.leftToRetry)
} else {

View File

@@ -21,6 +21,11 @@ import kotlinx.serialization.encoding.Encoder
* @see ByteArray.asMultipartFile
* @see ByteReadChannel.asMultipartFile
* @see ByteReadChannelAllocator.asMultipartFile
*
* @see fromInput
* @see fromFile
* @see fromId
* @see fromUrl
*/
@Serializable(InputFileSerializer::class)
sealed class InputFile {
@@ -29,9 +34,24 @@ sealed class InputFile {
companion object {
operator fun invoke(file: MPPFile) = file.asMultipartFile()
/**
* Creates [MultipartFile] based on incoming [filename] and [inputSource]
*/
fun fromInput(filename: String, inputSource: () -> Input) = MultipartFile(filename, inputSource)
/**
* Creates [MultipartFile] based on incoming [MPPFile] (common File in java, for example)
*/
fun fromFile(file: MPPFile) = invoke(file)
/**
* Creates [FileId] from the incomming [id] [String] with believe that it is [FileId]
*/
fun fromId(id: String) = FileId(id)
/**
* Creates [FileUrl] from the incomming [url] [String]
*/
fun fromUrl(url: String) = FileUrl(url)
}
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.abstracts
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.DeserializationStrategy

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.*

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.chat.invite_links
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.*

View File

@@ -2,8 +2,4 @@ package dev.inmo.tgbotapi.requests.send.abstracts
interface ThumbedSendMessageRequest<T: Any>: SendMessageRequest<T> {
val thumbnail: String?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnail"))
val thumb: String?
get() = thumbnail
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.requests.send.polls
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.TextedOutput
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest

View File

@@ -77,9 +77,6 @@ val UserId.userLink: String
get() = chatId.userLink
val User.userLink: String
get() = id.userLink
@Deprecated("Deprecated due to the conflicts in name", ReplaceWith("this.userLink", "dev.inmo.tgbotapi.types.userLink"))
val User.link: String
get() = userLink
typealias UserId = ChatId

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.WithUser
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.utils.RiskFeature

View File

@@ -375,17 +375,9 @@ const val stickerFileIdField = "sticker_file_id"
const val gameShortNameField = "game_short_name"
const val thumbnailUrlField = "thumbnail_url"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailUrlField", "dev.inmo.tgbotapi.types.thumbnailUrlField"))
const val thumbUrlField = "thumb_url"
const val thumbnailMimeTypeField = "thumbnail_mime_type"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailMimeTypeField", "dev.inmo.tgbotapi.types.thumbnailMimeTypeField"))
const val thumbMimeTypeField = "thumb_mime_type"
const val thumbnailWidthField = "thumbnail_width"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailWidthField", "dev.inmo.tgbotapi.types.thumbnailWidthField"))
const val thumbWidthField = "thumb_width"
const val thumbnailHeightField = "thumbnail_height"
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailHeightField", "dev.inmo.tgbotapi.types.thumbnailHeightField"))
const val thumbHeightField = "thumb_height"
const val inputMessageContentField = "input_message_content"
const val hideUrlField = "hide_url"
@@ -440,8 +432,6 @@ const val idField = "id"
const val pollIdField = "poll_id"
const val textField = "text"
const val thumbnailField = "thumbnail"
@Deprecated("Renamed (in telegram bot api)", ReplaceWith("thumbnailField", "dev.inmo.tgbotapi.types.thumbnailField"))
const val thumbField = "thumb"
const val emojiField = "emoji"
const val emojisField = "emojis"
const val titleField = "title"

View File

@@ -2,11 +2,5 @@ package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts
interface ThumbSizedInlineQueryResult : InlineQueryResult, ThumbedInlineQueryResult {
val thumbnailWidth: Int?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailWidth"))
val thumbWidth: Int?
get() = thumbnailWidth
val thumbnailHeight: Int?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailHeight"))
val thumbHeight: Int?
get() = thumbnailHeight
}

View File

@@ -4,14 +4,8 @@ import dev.inmo.tgbotapi.utils.MimeType
interface ThumbedInlineQueryResult : InlineQueryResult {
val thumbnailUrl: String?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailUrl"))
val thumbUrl: String?
get() = thumbnailUrl
}
interface ThumbedWithMimeTypeInlineQueryResult : ThumbedInlineQueryResult {
val thumbnailMimeType: MimeType?
@Deprecated("Renamed in telegram bot api", ReplaceWith("thumbnailMimeType"))
val thumbMimeType: MimeType?
get() = thumbnailMimeType
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
sealed class RequestError
@@ -10,7 +10,7 @@ data class RetryAfterError(
) : RequestError() {
val canContinue = (seconds * 1000L) + startCountingMillis
val leftToRetry: Long
get() = canContinue - DateTime.nowUnixLong()
get() = canContinue - DateTime.nowUnixMillisLong()
}
data class MigrateChatId(

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import kotlinx.serialization.*
@Serializable

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer

View File

@@ -14,12 +14,6 @@ const val UPDATE_POLL_ANSWER = "poll_answer"
const val UPDATE_MY_CHAT_MEMBER = "my_chat_member"
const val UPDATE_CHAT_MEMBER = "chat_member"
const val UPDATE_CHAT_JOIN_REQUEST = "chat_join_request"
@Deprecated("Renamed", ReplaceWith("UPDATE_MY_CHAT_MEMBER", "dev.inmo.tgbotapi.types.UPDATE_MY_CHAT_MEMBER"))
const val MY_CHAT_MEMBER = UPDATE_MY_CHAT_MEMBER
@Deprecated("Renamed", ReplaceWith("UPDATE_CHAT_MEMBER", "dev.inmo.tgbotapi.types.UPDATE_CHAT_MEMBER"))
const val CHAT_MEMBER = UPDATE_CHAT_MEMBER
@Deprecated("Renamed", ReplaceWith("UPDATE_CHAT_JOIN_REQUEST", "dev.inmo.tgbotapi.types.UPDATE_CHAT_JOIN_REQUEST"))
const val CHAT_JOIN_REQUEST = UPDATE_CHAT_JOIN_REQUEST
val ALL_UPDATES_LIST = listOf(
UPDATE_MESSAGE,

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.chat
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.FromUser
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.SerialName

View File

@@ -22,7 +22,7 @@ data class StickerSurrogate(
val height: Int,
val is_animated: Boolean? = null,
val is_video: Boolean? = null,
val thumb: PhotoSize? = null,
val thumbnail: PhotoSize? = null,
val emoji: String? = null,
val set_name: StickerSetName? = null,
val premium_animation: File? = null,
@@ -43,6 +43,7 @@ sealed interface Sticker : TelegramMediaFile, SizedMediaFile, ThumbedMediaFile {
get() = false
val isVideo
get() = false
val type: StickerType
fun asInputSticker(emojis: List<String> = emoji ?.let { listOf(it) } ?: error("Unable to create input sticker without emojis")): InputSticker
}
@@ -62,7 +63,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.file_unique_id,
surrogate.width,
surrogate.height,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.premium_animation,
@@ -73,7 +74,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.file_unique_id,
surrogate.width,
surrogate.height,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.premium_animation,
@@ -84,7 +85,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.file_unique_id,
surrogate.width,
surrogate.height,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.premium_animation,
@@ -98,7 +99,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.width,
surrogate.height,
surrogate.mask_position,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size
@@ -109,7 +110,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.width,
surrogate.height,
surrogate.mask_position,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size
@@ -120,7 +121,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.width,
surrogate.height,
surrogate.mask_position,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size
@@ -133,7 +134,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.width,
surrogate.height,
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size,
@@ -145,7 +146,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.width,
surrogate.height,
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size,
@@ -157,7 +158,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.width,
surrogate.height,
surrogate.custom_emoji_id ?: error("For custom emoji stickers field custom_emoji_id should be presented"),
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size,
@@ -169,7 +170,7 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.file_unique_id,
surrogate.width,
surrogate.height,
surrogate.thumb,
surrogate.thumbnail,
surrogate.emoji,
surrogate.set_name,
surrogate.file_size,
@@ -178,13 +179,35 @@ object StickerSerializer : KSerializer<Sticker> {
surrogate.is_video == true -> StickerFormat.Video
else -> StickerFormat.Static
},
surrogate.type,
json
)
}
}
override fun serialize(encoder: Encoder, value: Sticker) {
TODO("Not yet implemented")
with(value) {
StickerSurrogate.serializer().serialize(
encoder,
StickerSurrogate(
fileId,
fileUniqueId,
type,
width,
height,
isAnimated,
isVideo,
thumbnail,
emoji,
stickerSetName,
(this as? RegularSticker) ?.premiumAnimationFile,
(this as? MaskSticker) ?.maskPosition,
(this as? CustomEmojiSticker) ?.customEmojiId,
fileSize,
(this as? CustomEmojiSticker) ?.needsRepainting ?: false
)
)
}
}
}
@@ -210,6 +233,9 @@ sealed interface AnimatedSticker : Sticker {
sealed interface RegularSticker : Sticker {
val premiumAnimationFile: File?
override val type: StickerType.Regular
get() = StickerType.Regular
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(
fileId,
emojis,
@@ -241,6 +267,11 @@ data class RegularSimpleSticker(
@SerialName(stickerFormatField)
@EncodeDefault
override val stickerFormat: StickerFormat = StickerFormat.Static
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.Regular
get() = StickerType.Regular
}
@Serializable
@@ -263,7 +294,13 @@ data class RegularAnimatedSticker(
override val premiumAnimationFile: File? = null,
@SerialName(fileSizeField)
override val fileSize: Long? = null,
) : RegularSticker, AnimatedSticker
) : RegularSticker, AnimatedSticker {
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.Regular
get() = StickerType.Regular
}
@Serializable
data class RegularVideoSticker(
@SerialName(fileIdField)
@@ -284,13 +321,22 @@ data class RegularVideoSticker(
override val premiumAnimationFile: File? = null,
@SerialName(fileSizeField)
override val fileSize: Long? = null,
) : RegularSticker, VideoSticker
) : RegularSticker, VideoSticker {
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.Regular
get() = StickerType.Regular
}
@Serializable
sealed interface MaskSticker : Sticker {
val maskPosition: MaskPosition?
override val type: StickerType.Mask
get() = StickerType.Mask
override fun asInputSticker(emojis: List<String>) = InputSticker.Mask(
fileId,
emojis,
@@ -321,6 +367,12 @@ data class MaskSimpleSticker(
@SerialName(stickerFormatField)
@EncodeDefault
override val stickerFormat: StickerFormat = StickerFormat.Static
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.Mask
get() = StickerType.Mask
}
@Serializable
data class MaskAnimatedSticker(
@@ -342,7 +394,13 @@ data class MaskAnimatedSticker(
override val stickerSetName: StickerSetName? = null,
@SerialName(fileSizeField)
override val fileSize: Long? = null,
) : MaskSticker, AnimatedSticker
) : MaskSticker, AnimatedSticker {
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.Mask
get() = StickerType.Mask
}
@Serializable
data class MaskVideoSticker(
@SerialName(fileIdField)
@@ -363,13 +421,22 @@ data class MaskVideoSticker(
override val stickerSetName: StickerSetName? = null,
@SerialName(fileSizeField)
override val fileSize: Long? = null,
) : MaskSticker, VideoSticker
) : MaskSticker, VideoSticker {
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.Mask
get() = StickerType.Mask
}
@Serializable
sealed interface CustomEmojiSticker : Sticker {
val customEmojiId: CustomEmojiId
val needsRepainting: Boolean
override val type: StickerType.CustomEmoji
get() = StickerType.CustomEmoji
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.CustomEmoji(
fileId,
emojis,
@@ -403,6 +470,12 @@ data class CustomEmojiSimpleSticker(
@SerialName(stickerFormatField)
@EncodeDefault
override val stickerFormat: StickerFormat = StickerFormat.Static
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.CustomEmoji
get() = StickerType.CustomEmoji
}
@Serializable
data class CustomEmojiAnimatedSticker(
@@ -426,7 +499,13 @@ data class CustomEmojiAnimatedSticker(
override val fileSize: Long? = null,
@SerialName(needsRepaintingField)
override val needsRepainting: Boolean = false,
) : CustomEmojiSticker, AnimatedSticker
) : CustomEmojiSticker, AnimatedSticker {
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.CustomEmoji
get() = StickerType.CustomEmoji
}
@Serializable
data class CustomEmojiVideoSticker(
@SerialName(fileIdField)
@@ -449,7 +528,13 @@ data class CustomEmojiVideoSticker(
override val fileSize: Long? = null,
@SerialName(needsRepaintingField)
override val needsRepainting: Boolean = false,
) : CustomEmojiSticker, VideoSticker
) : CustomEmojiSticker, VideoSticker {
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
@EncodeDefault
override val type: StickerType.CustomEmoji
get() = StickerType.CustomEmoji
}
@Serializable
data class UnknownSticker(
@@ -471,6 +556,9 @@ data class UnknownSticker(
override val fileSize: Long? = null,
@SerialName(stickerFormatField)
override val stickerFormat: StickerFormat = StickerFormat.Static,
@SerialName(stickerTypeField)
@Serializable(StickerType.Serializer::class)
override val type: StickerType = StickerType.Regular,
val raw: JsonElement
) : Sticker {
override fun asInputSticker(emojis: List<String>) = InputSticker.WithKeywords.Regular(

View File

@@ -2,8 +2,4 @@ package dev.inmo.tgbotapi.types.files
sealed interface ThumbedMediaFile : TelegramMediaFile {
val thumbnail: PhotoSize?
@Deprecated("Renamed (in telegram bot api)", ReplaceWith("thumbnail"))
val thumb: PhotoSize?
get() = thumbnail
}

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.ChannelChat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.ChannelChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.message.ChatEvents.voice
import com.soywiz.klock.TimeSpan
import com.soywiz.klock.seconds
import korlibs.time.TimeSpan
import korlibs.time.seconds
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.durationField
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.VideoChatEvent

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.GroupChat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.SupergroupChat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.*

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.User
import dev.inmo.tgbotapi.types.chat.Chat

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.*

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.types.message.abstracts
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.WithChat
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.MessageId

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.message.abstracts
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
interface PossiblyEditedMessage : Message {
val editDate: DateTime?
}
}

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.message.content
import dev.inmo.tgbotapi.abstracts.SpoilerableData
import dev.inmo.tgbotapi.abstracts.TextedInput
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.ChatIdentifier
@@ -51,6 +52,18 @@ sealed interface MessageContent: ResendableContent {
additionalBuilder()
}
polymorphic(TextedContent::class) {
subclass(TextContent::class)
subclass(VoiceContent::class)
subclass(MediaGroupContent::class)
subclass(AudioContent::class)
subclass(DocumentContent::class)
subclass(VideoContent::class)
subclass(PhotoContent::class)
subclass(AnimationContent::class)
}
polymorphic(MediaCollectionContent::class) {
subclass(PhotoContent::class)
@@ -115,6 +128,11 @@ sealed interface MediaCollectionContent<T: TelegramMediaFile>: MessageContent, M
val mediaCollection: List<T>
}
/**
* All the subtypes of this content will have [text] and [textSources] fields
*/
sealed interface TextedContent : MessageContent, TextedInput
sealed interface MediaContent: MessageContent {
val media: TelegramMediaFile
fun asTelegramMedia(): TelegramMedia

View File

@@ -22,7 +22,7 @@ sealed interface DocumentMediaGroupPartContent : MediaGroupPartContent {
override fun toMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia
}
sealed interface TextedMediaContent : MediaContent, TextedInput
sealed interface TextedMediaContent : TextedContent, MediaContent
sealed interface MediaGroupCollectionContent<T : MediaGroupPartContent> : TextedMediaContent {
@Serializable

View File

@@ -15,7 +15,7 @@ import kotlinx.serialization.Serializable
data class TextContent(
override val text: String,
override val textSources: TextSourcesList = emptyList(),
) : MessageContent, TextedInput {
) : TextedContent {
override fun createResend(
chatId: ChatIdentifier,
messageThreadId: MessageThreadId?,

View File

@@ -2,6 +2,8 @@ package dev.inmo.tgbotapi.types.message.content
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
typealias TextedMessage = CommonMessage<TextedContent>
typealias InvoiceMessage = CommonMessage<InvoiceContent>
typealias VenueMessage = CommonMessage<VenueContent>
typealias GameMessage = CommonMessage<GameContent>

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.types.polls
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import korlibs.time.DateTime
import korlibs.time.TimeSpan
import dev.inmo.tgbotapi.abstracts.TextedInput
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.*

View File

@@ -32,9 +32,6 @@ sealed interface StickerSet {
val isVideo: Boolean
get() = false
val thumbnail: PhotoSize?
@Deprecated("Renamed in telegram bot api")
val thumb: PhotoSize?
get() = thumbnail
object Serializer : KSerializer<StickerSet> {
override val descriptor: SerialDescriptor = JsonElement.serializer().descriptor

View File

@@ -1,6 +1,6 @@
package dev.inmo.tgbotapi.utils
import com.soywiz.krypto.*
import korlibs.crypto.*
import io.ktor.http.decodeURLQueryComponent
import io.ktor.utils.io.core.toByteArray

View File

@@ -1,12 +1,12 @@
package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.tgbotapi.TestsJsonFormat
import kotlinx.serialization.Serializable
import kotlin.test.Test
import kotlin.test.assertEquals
private val dateTimeUnix = DateTime.nowUnixLong()
private val dateTimeUnix = DateTime.nowUnixMillisLong()
private val dateTimeMillis = dateTimeUnix * 1000
private val dateTime = DateTime(dateTimeMillis)

View File

@@ -329,6 +329,7 @@ import dev.inmo.tgbotapi.types.message.content.SpoilerableMediaContent
import dev.inmo.tgbotapi.types.message.content.StaticLocationContent
import dev.inmo.tgbotapi.types.message.content.StickerContent
import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextedContent
import dev.inmo.tgbotapi.types.message.content.TextedMediaContent
import dev.inmo.tgbotapi.types.message.content.VenueContent
import dev.inmo.tgbotapi.types.message.content.VideoContent
@@ -3712,6 +3713,15 @@ public inline fun <T>
ResendableContent.ifMediaCollectionContent(block: (MediaCollectionContent<TelegramMediaFile>) -> T):
T? = mediaCollectionContentOrNull() ?.let(block)
public inline fun ResendableContent.textedContentOrNull(): TextedContent? = this as?
dev.inmo.tgbotapi.types.message.content.TextedContent
public inline fun ResendableContent.textedContentOrThrow(): TextedContent = this as
dev.inmo.tgbotapi.types.message.content.TextedContent
public inline fun <T> ResendableContent.ifTextedContent(block: (TextedContent) -> T): T? =
textedContentOrNull() ?.let(block)
public inline fun ResendableContent.mediaContentOrNull(): MediaContent? = this as?
dev.inmo.tgbotapi.types.message.content.MediaContent

View File

@@ -47,7 +47,7 @@ fun makeLinkToMessage(
username: Username,
messageId: MessageId,
threadId: MessageThreadId? = null
): String = makeLinkToMessage(username.username, messageId, threadId)
): String = makeLinkToMessage(username.usernameWithoutAt, messageId, threadId)
fun makeLinkToMessage(
chatId: Identifier,
messageId: MessageId,

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.shortcuts
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import korlibs.time.DateTime
import korlibs.time.TimeSpan
import dev.inmo.tgbotapi.types.LongSeconds
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.polls.ApproximateScheduledCloseInfo