mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-16 20:10:18 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 174706b189 | |||
| fe17312bb5 | |||
| d8b5789cd2 | |||
| f27d0916db | |||
| fa0a2818a0 | |||
| 2d3fe45389 | |||
| 02b5d282d3 | |||
| 7795bc2b50 | |||
| a95365a691 | |||
| 07082bf896 | |||
| 6a3fc47f62 | |||
| 1c94e86b40 | |||
| 0416b200b8 | |||
| 48c4e90912 | |||
| 5fc88e89b9 | |||
| dad42cf939 | |||
| 041c3ecc1b | |||
| 103dd949ce |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,5 +1,25 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 5.2.1
|
||||
|
||||
* `Core`:
|
||||
* All the `CallbackQuery`es now will receive `CommonUser` instead of `User` due inability of bots to trigger any
|
||||
inline interaction with others bots
|
||||
* `API`:
|
||||
* Now `sentMessageFlow` will take each sent message in `handleLiveLocation`
|
||||
|
||||
## 5.2.0
|
||||
|
||||
* `Versions`:
|
||||
* `MicroUtils`: `0.16.8` -> `0.16.10`
|
||||
|
||||
## 5.1.1
|
||||
|
||||
* `Core`:
|
||||
* Add opportunity to get user link with `makeUserLink`
|
||||
* `BehaviourBuilder`:
|
||||
* Fixes in content waiting expectators
|
||||
|
||||
## 5.1.0
|
||||
|
||||
[Bot API 6.5](https://core.telegram.org/bots/api-changelog#february-3-2023) support
|
||||
|
||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=5.1.0
|
||||
library_version=5.2.1
|
||||
|
||||
@@ -13,7 +13,7 @@ ktor = "2.2.3"
|
||||
ksp = "1.7.22-1.0.8"
|
||||
kotlin-poet = "1.12.0"
|
||||
|
||||
microutils = "0.16.8"
|
||||
microutils = "0.16.10"
|
||||
|
||||
github-release-plugin = "2.4.1"
|
||||
dokka = "1.7.20"
|
||||
|
||||
@@ -6,7 +6,6 @@ import dev.inmo.tgbotapi.abstracts.*
|
||||
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.extensions.api.edit.edit
|
||||
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
|
||||
import dev.inmo.tgbotapi.extensions.api.send.send
|
||||
import dev.inmo.tgbotapi.extensions.api.send.sendLiveLocation
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
@@ -17,6 +16,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.LocationContent
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.js.JsName
|
||||
@@ -45,7 +45,8 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
sentMessageFlow: FlowCollector<ContentMessage<LocationContent>>? = null
|
||||
) {
|
||||
var currentLiveLocationMessage: ContentMessage<LocationContent>? = null
|
||||
val updateMessageJob = CoroutineScope(currentCoroutineContext().LinkedSupervisorJob()).launchSafelyWithoutExceptions(start = CoroutineStart.LAZY) {
|
||||
@@ -73,7 +74,9 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
replyToMessageId,
|
||||
allowSendingWithoutReply,
|
||||
it.replyMarkup
|
||||
)
|
||||
).also {
|
||||
sentMessageFlow ?.emit(it)
|
||||
}
|
||||
} else {
|
||||
edit(
|
||||
capturedLiveLocationMessage,
|
||||
@@ -83,7 +86,9 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
it.heading,
|
||||
it.proximityAlertRadius,
|
||||
it.replyMarkup
|
||||
)
|
||||
).also {
|
||||
sentMessageFlow ?.emit(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,7 +107,8 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
sentMessageFlow: FlowCollector<ContentMessage<LocationContent>>? = null
|
||||
) {
|
||||
handleLiveLocation(
|
||||
chatId,
|
||||
@@ -121,7 +127,8 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
disableNotification,
|
||||
protectContent,
|
||||
replyToMessageId,
|
||||
allowSendingWithoutReply
|
||||
allowSendingWithoutReply,
|
||||
sentMessageFlow
|
||||
)
|
||||
}
|
||||
|
||||
@@ -139,7 +146,8 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyToMessageId: MessageId? = null,
|
||||
allowSendingWithoutReply: Boolean? = null
|
||||
allowSendingWithoutReply: Boolean? = null,
|
||||
sentMessageFlow: FlowCollector<ContentMessage<LocationContent>>? = null
|
||||
) {
|
||||
handleLiveLocation(
|
||||
chatId,
|
||||
@@ -154,6 +162,7 @@ suspend fun TelegramBot.handleLiveLocation(
|
||||
disableNotification,
|
||||
protectContent,
|
||||
replyToMessageId,
|
||||
allowSendingWithoutReply
|
||||
allowSendingWithoutReply,
|
||||
sentMessageFlow
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,15 +2,22 @@ package dev.inmo.tgbotapi.extensions.api
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import com.soywiz.klock.TimeSpan
|
||||
import dev.inmo.micro_utils.coroutines.LinkedSupervisorJob
|
||||
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
|
||||
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.extensions.api.edit.edit
|
||||
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
|
||||
import dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation
|
||||
import dev.inmo.tgbotapi.extensions.api.send.send
|
||||
import dev.inmo.tgbotapi.extensions.api.send.sendLiveLocation
|
||||
import dev.inmo.tgbotapi.requests.send.SendLiveLocation
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.location.LiveLocation
|
||||
import dev.inmo.tgbotapi.types.location.Location
|
||||
import dev.inmo.tgbotapi.types.location.StaticLocation
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
@@ -18,7 +25,15 @@ import dev.inmo.tgbotapi.types.message.content.LocationContent
|
||||
import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull
|
||||
import io.ktor.utils.io.core.Closeable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.js.JsName
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.math.ceil
|
||||
|
||||
val defaultLivePeriodDelayMillis = (livePeriodLimit.last - 60L) * 1000L
|
||||
@@ -45,7 +60,8 @@ class LiveLocationProvider internal constructor(
|
||||
private set
|
||||
get() = field || leftUntilCloseMillis.millisecondsLong < 0L
|
||||
|
||||
private var message: ContentMessage<LocationContent> = initMessage
|
||||
var message: ContentMessage<LocationContent> = initMessage
|
||||
private set
|
||||
val lastLocation: LiveLocation
|
||||
get() = message.content.location as LiveLocation
|
||||
|
||||
|
||||
@@ -16,119 +16,176 @@ typealias CommonMessageToContentMapper<T> = suspend CommonMessage<T>.() -> T?
|
||||
@RiskFeature(lowLevelRiskFeatureMessage)
|
||||
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContent(
|
||||
initRequest: Request<*>? = null,
|
||||
includeMediaGroups: Boolean = true,
|
||||
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
||||
): Flow<O> = waitContentMessage<O>(initRequest, includeMediaGroups, errorFactory).map { it.content }
|
||||
): Flow<O> = waitContentMessage<O>(initRequest, errorFactory).map { it.content }
|
||||
|
||||
|
||||
@Deprecated(
|
||||
includeMediaGroupsDeprecationMessage,
|
||||
ReplaceWith("waitAnyContent(initRequest, errorFactory)", "dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitAnyContent")
|
||||
)
|
||||
suspend fun BehaviourContext.waitContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContent<MessageContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<MessageContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAnyContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<MessageContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitContact(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<ContactContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<ContactContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitDice(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<DiceContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<DiceContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitGame(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<GameContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<GameContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitLocation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<LocationContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<LocationContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitLiveLocation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<LiveLocationContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<LiveLocationContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitStaticLocation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<StaticLocationContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<StaticLocationContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitPoll(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<PollContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<PollContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitText(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<TextContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<TextContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVenue(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VenueContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<VenueContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContent<AudioMediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContent<DocumentMediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitMedia(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContent<MediaContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<MediaContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitMedia(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<MediaContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContent<MediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<MediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<MediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContent<VisualMediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitTextedMediaContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContent<TextedMediaContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<TextedMediaContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitTextedMediaContent(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<TextedMediaContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAnimation(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<AnimationContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<AnimationContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitAudio(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContent<AudioContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<AudioContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAudio(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<AudioContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitDocument(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContent<DocumentContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<DocumentContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitDocument(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<DocumentContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitPhoto(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContent<PhotoContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<PhotoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitPhoto(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContent<PhotoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitSticker(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<StickerContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<StickerContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitVideo(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContent<VideoContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContent<VideoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVideo(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VideoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVideoNote(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VideoNoteContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<VideoNoteContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVoice(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<VoiceContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<VoiceContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitInvoice(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent<InvoiceContent>(initRequest, false, errorFactory)
|
||||
) = waitContent<InvoiceContent>(initRequest, errorFactory)
|
||||
|
||||
@@ -13,17 +13,20 @@ import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
const val includeMediaGroupsDeprecationMessage = "includeMediaGroups is deprecated and its usage will not lead to any changes"
|
||||
typealias CommonMessageToCommonMessageMapper<T> = suspend CommonMessage<T>.() -> CommonMessage<T>?
|
||||
|
||||
@RiskFeature(lowLevelRiskFeatureMessage)
|
||||
suspend inline fun <reified O : MessageContent> BehaviourContext.waitContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
includeMediaGroups: Boolean = true,
|
||||
noinline errorFactory: NullableRequestBuilder<*> = { null }
|
||||
): Flow<CommonMessage<O>> = expectFlow(
|
||||
initRequest,
|
||||
errorFactory
|
||||
) {
|
||||
if (it !is BaseSentMessageUpdate) {
|
||||
return@expectFlow emptyList()
|
||||
}
|
||||
listOfNotNull((it.data as? CommonMessage<*>) ?.withContent<O>())
|
||||
}
|
||||
|
||||
@@ -44,114 +47,172 @@ internal inline fun <reified T : MessageContent> contentMessageConverter(
|
||||
if (content is T) this as CommonMessage<T> else null
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
includeMediaGroupsDeprecationMessage,
|
||||
ReplaceWith("waitAnyContentMessage(initRequest, errorFactory)", "dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitAnyContentMessage")
|
||||
)
|
||||
suspend fun BehaviourContext.waitContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContentMessage<MessageContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<MessageContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAnyContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
) = waitContentMessage<MessageContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitContactMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<ContactContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<ContactContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitDiceMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<DiceContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<DiceContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitGameMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<GameContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<GameContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitLocationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<LocationContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<LocationContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitLiveLocationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<LiveLocationContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<LiveLocationContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitStaticLocationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<StaticLocationContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<StaticLocationContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitPollMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<PollContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<PollContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitTextMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<TextContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<TextContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVenueMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VenueContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<VenueContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContentMessage<AudioMediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAudioMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<AudioMediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContentMessage<DocumentMediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<DocumentMediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitMediaMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContentMessage<MediaContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<MediaContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitMediaMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<MediaContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContentMessage<MediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<MediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAnyMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<MediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVisualMediaGroupContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VisualMediaGroupPartContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitTextedMediaContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = true
|
||||
) = waitContentMessage<TextedMediaContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<TextedMediaContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitTextedMediaContentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<TextedMediaContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAnimationMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<AnimationContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<AnimationContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitAudioMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContentMessage<AudioContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<AudioContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitAudioMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<AudioContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitDocumentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContentMessage<DocumentContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<DocumentContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitDocumentMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<DocumentContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitPhotoMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContentMessage<PhotoContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<PhotoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitPhotoMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<PhotoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitStickerMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<StickerContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<StickerContent>(initRequest, errorFactory)
|
||||
@Deprecated(includeMediaGroupsDeprecationMessage)
|
||||
suspend fun BehaviourContext.waitVideoMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null },
|
||||
includeMediaGroups: Boolean = false
|
||||
) = waitContentMessage<VideoContent>(initRequest, includeMediaGroups, errorFactory)
|
||||
includeMediaGroups: Boolean
|
||||
) = waitContentMessage<VideoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVideoMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VideoContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVideoNoteMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VideoNoteContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<VideoNoteContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitVoiceMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<VoiceContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<VoiceContent>(initRequest, errorFactory)
|
||||
suspend fun BehaviourContext.waitInvoiceMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage<InvoiceContent>(initRequest, false, errorFactory)
|
||||
) = waitContentMessage<InvoiceContent>(initRequest, errorFactory)
|
||||
|
||||
@@ -14,6 +14,7 @@ import kotlinx.serialization.json.longOrNull
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
const val internalLinkBeginning = "https://t.me"
|
||||
const val internalUserLinkBeginning = "tg://user?id="
|
||||
|
||||
@Serializable(ChatIdentifierSerializer::class)
|
||||
@ClassCastsIncluded
|
||||
@@ -66,7 +67,7 @@ fun IdChatIdentifier.toChatWithThreadId(threadId: MessageThreadId) = IdChatIdent
|
||||
*/
|
||||
@Warning("This API have restrictions in Telegram System")
|
||||
val Identifier.userLink: String
|
||||
get() = "tg://user?id=$this"
|
||||
get() = "$internalUserLinkBeginning$this"
|
||||
/**
|
||||
* https://core.telegram.org/bots/api#formatting-options
|
||||
*/
|
||||
|
||||
@@ -2,16 +2,18 @@ package dev.inmo.tgbotapi.types.queries.callback
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.FromUser
|
||||
import dev.inmo.tgbotapi.types.CallbackQueryIdentifier
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
|
||||
sealed interface CallbackQuery : FromUser {
|
||||
val id: CallbackQueryIdentifier
|
||||
val chatInstance: String
|
||||
override val from: CommonUser
|
||||
}
|
||||
|
||||
data class UnknownCallbackQueryType(
|
||||
override val id: CallbackQueryIdentifier,
|
||||
override val from: User,
|
||||
override val from: CommonUser,
|
||||
override val chatInstance: String,
|
||||
val raw: String
|
||||
) : CallbackQuery
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package dev.inmo.tgbotapi.types.queries.callback
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class InlineMessageIdDataCallbackQuery(
|
||||
override val id: CallbackQueryIdentifier,
|
||||
override val from: User,
|
||||
override val from: CommonUser,
|
||||
override val chatInstance: String,
|
||||
override val inlineMessageId: InlineMessageIdentifier,
|
||||
override val data: String
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package dev.inmo.tgbotapi.types.queries.callback
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
|
||||
data class InlineMessageIdGameShortNameCallbackQuery(
|
||||
override val id: CallbackQueryIdentifier,
|
||||
override val from: User,
|
||||
override val from: CommonUser,
|
||||
override val chatInstance: String,
|
||||
override val inlineMessageId: InlineMessageIdentifier,
|
||||
override val gameShortName: String
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package dev.inmo.tgbotapi.types.queries.callback
|
||||
|
||||
import dev.inmo.tgbotapi.types.CallbackQueryIdentifier
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
data class MessageDataCallbackQuery(
|
||||
override val id: CallbackQueryIdentifier,
|
||||
override val from: User,
|
||||
override val from: CommonUser,
|
||||
override val chatInstance: String,
|
||||
override val message: ContentMessage<MessageContent>,
|
||||
override val data: String
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package dev.inmo.tgbotapi.types.queries.callback
|
||||
|
||||
import dev.inmo.tgbotapi.types.CallbackQueryIdentifier
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
data class MessageGameShortNameCallbackQuery(
|
||||
override val id: CallbackQueryIdentifier,
|
||||
override val from: User,
|
||||
override val from: CommonUser,
|
||||
override val chatInstance: String,
|
||||
override val message: ContentMessage<MessageContent>,
|
||||
override val gameShortName: String
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.queries.callback
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializer
|
||||
@@ -13,7 +14,7 @@ internal data class RawCallbackQuery(
|
||||
@SerialName(idField)
|
||||
val id: CallbackQueryIdentifier,
|
||||
@SerialName(fromField)
|
||||
val from: User,
|
||||
val from: CommonUser,
|
||||
@Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class)
|
||||
val message: ContentMessage<MessageContent>? = null,
|
||||
@SerialName(inlineMessageIdField)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils
|
||||
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
@@ -34,3 +35,10 @@ fun <MC : MessageContent, M : ContentMessage<MC>> Flow<M>.onlySentViaBot() = map
|
||||
fun <MC : MessageContent, M : ContentMessage<MC>> Flow<M>.withoutSentViaBot() = filter {
|
||||
it !is PossiblySentViaBot || it.senderBot == null
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the messages and checking that incoming [ContentMessage.content] is not [MediaGroupContent]
|
||||
*/
|
||||
fun <MC : MessageContent, M : ContentMessage<MC>> Flow<M>.withoutMediaGroups() = filter {
|
||||
it.content !is MediaGroupContent<*>
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.ktor.http.encodeURLQueryComponent
|
||||
|
||||
|
||||
fun makeUsernameLink(username: String, threadId: MessageThreadId? = null) = "$internalLinkBeginning/$username${threadId ?.let { "/$it" } ?: ""}"
|
||||
fun makeUserLink(userId: UserId) = userId.userLink
|
||||
fun makeChatLink(identifier: Identifier, threadId: MessageThreadId? = null) = identifier.toString().replace(
|
||||
linkIdRedundantPartRegex,
|
||||
""
|
||||
|
||||
Reference in New Issue
Block a user