1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-12-29 17:39:22 +00:00

Compare commits

...

3 Commits

17 changed files with 83 additions and 52 deletions

View File

@@ -139,10 +139,10 @@ suspend fun BehaviourContext.waitMediaContent(
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<MediaContent>()
suspend fun BehaviourContext.waitScheduledGiveawayContent(
suspend fun BehaviourContext.waitGiveawayContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContent(initRequest, errorFactory).mapContent<ScheduledGiveawayContent>()
) = waitContent(initRequest, errorFactory).mapContent<GiveawayContent>()
suspend fun BehaviourContext.waitGiveawayPublicResultsContent(
initRequest: Request<*>? = null,

View File

@@ -2,9 +2,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
@@ -13,7 +11,6 @@ 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>?
@@ -153,10 +150,10 @@ suspend fun BehaviourContext.waitMediaContentMessage(
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage(initRequest, errorFactory).mapWithContent<MediaContent>()
suspend fun BehaviourContext.waitScheduledGiveawayContentMessage(
suspend fun BehaviourContext.waitGiveawayContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitContentMessage(initRequest, errorFactory).mapWithContent<ScheduledGiveawayContent>()
) = waitContentMessage(initRequest, errorFactory).mapWithContent<GiveawayContent>()
suspend fun BehaviourContext.waitGiveawayPublicResultsContentMessage(
initRequest: Request<*>? = null,

View File

@@ -131,10 +131,10 @@ suspend fun BehaviourContext.waitEditedInvoice(
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContent<InvoiceContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedScheduledGiveawayContent(
suspend fun BehaviourContext.waitEditedGiveawayContent(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContent<ScheduledGiveawayContent>(initRequest, false, errorFactory)
) = waitEditedContent<GiveawayContent>(initRequest, false, errorFactory)
suspend fun BehaviourContext.waitEditedGiveawayPublicResultsContent(
initRequest: Request<*>? = null,

View File

@@ -3,7 +3,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.baseEditMessageUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.commonMessageOrNull
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.requests.abstracts.Request
@@ -137,10 +136,10 @@ suspend fun BehaviourContext.waitEditedInvoiceMessage(
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<InvoiceContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitEditedScheduledGiveawayContentMessage(
suspend fun BehaviourContext.waitEditedGiveawayContentMessage(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
) = waitEditedContentMessage<ScheduledGiveawayContent>(initRequest, errorFactory)
) = waitEditedContentMessage<GiveawayContent>(initRequest, errorFactory)
suspend fun BehaviourContext.waitEditedGiveawayPublicResultsContentMessage(
initRequest: Request<*>? = null,

View File

@@ -0,0 +1,38 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatIdChatMessageReactionUpdatedMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatIdChatMessageReactionsCountUpdatedMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByIdPollMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.chatMessageReactionUpdatedUpdateOrNull
import dev.inmo.tgbotapi.extensions.utils.chatMessageReactionsCountUpdatedUpdateOrNull
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionsCountUpdated
import dev.inmo.tgbotapi.types.polls.*
import dev.inmo.tgbotapi.types.update.abstracts.Update
/**
* @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.onChatMessageReactionsCountUpdated(
initialFilter: SimpleFilter<ChatMessageReactionsCountUpdated>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatMessageReactionsCountUpdated, Update>? = null,
markerFactory: MarkerFactory<ChatMessageReactionsCountUpdated, Any> = ByChatIdChatMessageReactionsCountUpdatedMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatMessageReactionsCountUpdated>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.chatMessageReactionsCountUpdatedUpdateOrNull() ?.data) ?.let(::listOfNotNull)
}

View File

@@ -716,8 +716,8 @@ suspend fun <BC : BehaviourContext> BC.onMediaContent(
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
* data
*/
suspend fun <BC : BehaviourContext> BC.onScheduledGiveawayContent(
initialFilter: CommonMessageFilter<ScheduledGiveawayContent>? = null,
suspend fun <BC : BehaviourContext> BC.onGiveawayContent(
initialFilter: CommonMessageFilter<GiveawayContent>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ScheduledGiveawayContentMessage, Update>? = MessageFilterByChat,
markerFactory: MarkerFactory<in ScheduledGiveawayContentMessage, Any> = ByChatMessageMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ScheduledGiveawayContentMessage>

View File

@@ -0,0 +1,8 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionsCountUpdated
object ByChatIdChatMessageReactionsCountUpdatedMarkerFactory : MarkerFactory<ChatMessageReactionsCountUpdated, Any> {
override suspend fun invoke(data: ChatMessageReactionsCountUpdated) = data.chat.id
}

View File

@@ -99,7 +99,7 @@ value class Username(
get() = withoutAt
init {
if (!username.startsWith("@")) {
if (!full.startsWith("@")) {
throw IllegalArgumentException("Username must starts with `@`")
}
}
@@ -132,7 +132,7 @@ object ChatIdentifierSerializer : KSerializer<ChatIdentifier> {
override fun serialize(encoder: Encoder, value: ChatIdentifier) {
when (value) {
is IdChatIdentifier -> encoder.encodeLong(value.chatId)
is Username -> encoder.encodeString(value.username)
is Username -> encoder.encodeString(value.full)
}
}
}
@@ -170,7 +170,7 @@ object FullChatIdentifierSerializer : KSerializer<ChatIdentifier> {
when (value) {
is ChatId -> encoder.encodeLong(value.chatId)
is ChatIdWithThreadId -> encoder.encodeString("${value.chatId}/${value.threadId}")
is Username -> encoder.encodeString(value.username)
is Username -> encoder.encodeString(value.full)
}
}
}

View File

@@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.types.dice.Dice
import dev.inmo.tgbotapi.types.files.*
import dev.inmo.tgbotapi.types.games.RawGame
import dev.inmo.tgbotapi.types.giveaway.GiveawayPublicResults
import dev.inmo.tgbotapi.types.giveaway.ScheduledGiveaway
import dev.inmo.tgbotapi.types.giveaway.Giveaway
import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.message.MessageOrigin
import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
@@ -96,7 +96,7 @@ sealed interface ReplyInfo {
private val poll: Poll? = null,
private val invoice: Invoice? = null,
private val dice: Dice? = null,
private val giveaway: ScheduledGiveaway? = null,
private val giveaway: Giveaway? = null,
private val giveaway_winners: GiveawayPublicResults? = null,
) {
val asExternalReplyInfo: External

View File

@@ -1,19 +1,13 @@
package dev.inmo.tgbotapi.types.giveaway
import dev.inmo.micro_utils.language_codes.IetfLang
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.giveaway.GiveawayInfo
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PublicChatEvent
import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ScheduledGiveaway(
data class Giveaway(
@SerialName(chatsField)
val chats: List<PreviewChat>,
@SerialName(winnersSelectionDateField)

View File

@@ -10,7 +10,7 @@ import dev.inmo.tgbotapi.types.files.*
import dev.inmo.tgbotapi.types.files.Sticker
import dev.inmo.tgbotapi.types.games.RawGame
import dev.inmo.tgbotapi.types.giveaway.*
import dev.inmo.tgbotapi.types.message.content.ScheduledGiveawayContent
import dev.inmo.tgbotapi.types.message.content.GiveawayContent
import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
@@ -96,7 +96,7 @@ internal data class RawMessage(
private val invoice: Invoice? = null,
private val dice: Dice? = null,
private val successful_payment: SuccessfulPayment? = null,
private val giveaway: ScheduledGiveaway? = null,
private val giveaway: Giveaway? = null,
private val giveaway_winners: GiveawayResults? = null,
private val users_shared: UsersShared? = null,
@@ -199,7 +199,7 @@ internal data class RawMessage(
venue != null -> VenueContent(venue)
poll != null -> PollContent(poll)
invoice != null -> InvoiceContent(invoice)
giveaway != null -> ScheduledGiveawayContent(chat, messageId, giveaway)
giveaway != null -> GiveawayContent(chat, messageId, giveaway)
giveaway_winners is GiveawayPublicResults -> GiveawayPublicResultsContent(giveaway_winners)
else -> null
}

View File

@@ -50,7 +50,7 @@ sealed interface MessageContent: ResendableContent {
subclass(InvoiceContent::class)
subclass(StoryContent::class)
subclass(GiveawayPublicResultsContent::class)
subclass(ScheduledGiveawayContent::class)
subclass(GiveawayContent::class)
additionalBuilder()
}

View File

@@ -1,23 +1,19 @@
package dev.inmo.tgbotapi.types.message.content
import dev.inmo.micro_utils.language_codes.IetfLang
import dev.inmo.tgbotapi.requests.ForwardMessage
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.giveaway.GiveawayInfo
import dev.inmo.tgbotapi.types.giveaway.ScheduledGiveaway
import dev.inmo.tgbotapi.types.giveaway.Giveaway
import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ScheduledGiveawayContent(
data class GiveawayContent(
private val chat: Chat,
private val messageId: MessageId,
val giveaway: ScheduledGiveaway
val giveaway: Giveaway
) : MessageContent {
override fun createResend(
chatId: ChatIdentifier,

View File

@@ -32,7 +32,7 @@ typealias VisualMediaGroupMessage = CommonMessage<VisualMediaGroupPartContent>
typealias VideoMessage = CommonMessage<VideoContent>
typealias PhotoMessage = CommonMessage<PhotoContent>
typealias AnimationMessage = CommonMessage<AnimationContent>
typealias ScheduledGiveawayContentMessage = CommonMessage<ScheduledGiveawayContent>
typealias ScheduledGiveawayContentMessage = CommonMessage<GiveawayContent>
typealias GiveawayPublicResultsContentMessage = CommonMessage<GiveawayPublicResultsContent>

View File

@@ -45,5 +45,5 @@ inline fun mention(vararg parts: TextSource) = mention(parts.toList())
inline fun mention(whoToMention: String) = mention(regular(whoToMention))
@Suppress("NOTHING_TO_INLINE")
inline fun mention(whoToMention: Username) = mention(whoToMention.username.dropWhile { it == '@' })
inline fun mention(whoToMention: Username) = mention(whoToMention.full.dropWhile { it == '@' })

View File

@@ -33,10 +33,10 @@ class ChatIdentifierTests {
@Test
fun `Cast_from_String_to_Username_is_working_correctly`() {
assertEquals(testUsername, testUsername.toUsername().username)
assertEquals(testUsername, testUsername.toUsername().full)
assertFails("Username creating must fail when trying to create from string which is not starting from @ symbol") {
testUsername.replace("@", "").toUsername().username
testUsername.replace("@", "").toUsername().full
}
}

View File

@@ -298,6 +298,7 @@ import dev.inmo.tgbotapi.types.message.content.DiceContent
import dev.inmo.tgbotapi.types.message.content.DocumentContent
import dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupPartContent
import dev.inmo.tgbotapi.types.message.content.GameContent
import dev.inmo.tgbotapi.types.message.content.GiveawayContent
import dev.inmo.tgbotapi.types.message.content.GiveawayPublicResultsContent
import dev.inmo.tgbotapi.types.message.content.InvoiceContent
import dev.inmo.tgbotapi.types.message.content.LiveLocationContent
@@ -311,7 +312,6 @@ import dev.inmo.tgbotapi.types.message.content.MessageContent
import dev.inmo.tgbotapi.types.message.content.PhotoContent
import dev.inmo.tgbotapi.types.message.content.PollContent
import dev.inmo.tgbotapi.types.message.content.ResendableContent
import dev.inmo.tgbotapi.types.message.content.ScheduledGiveawayContent
import dev.inmo.tgbotapi.types.message.content.SpoilerableMediaContent
import dev.inmo.tgbotapi.types.message.content.StaticLocationContent
import dev.inmo.tgbotapi.types.message.content.StickerContent
@@ -3795,6 +3795,15 @@ public inline fun ResendableContent.gameContentOrThrow(): GameContent = this as
public inline fun <T> ResendableContent.ifGameContent(block: (GameContent) -> T): T? =
gameContentOrNull() ?.let(block)
public inline fun ResendableContent.giveawayContentOrNull(): GiveawayContent? = this as?
dev.inmo.tgbotapi.types.message.content.GiveawayContent
public inline fun ResendableContent.giveawayContentOrThrow(): GiveawayContent = this as
dev.inmo.tgbotapi.types.message.content.GiveawayContent
public inline fun <T> ResendableContent.ifGiveawayContent(block: (GiveawayContent) -> T): T? =
giveawayContentOrNull() ?.let(block)
public inline fun ResendableContent.giveawayPublicResultsContentOrNull():
GiveawayPublicResultsContent? = this as?
dev.inmo.tgbotapi.types.message.content.GiveawayPublicResultsContent
@@ -3874,16 +3883,6 @@ public inline fun ResendableContent.pollContentOrThrow(): PollContent = this as
public inline fun <T> ResendableContent.ifPollContent(block: (PollContent) -> T): T? =
pollContentOrNull() ?.let(block)
public inline fun ResendableContent.scheduledGiveawayContentOrNull(): ScheduledGiveawayContent? =
this as? dev.inmo.tgbotapi.types.message.content.ScheduledGiveawayContent
public inline fun ResendableContent.scheduledGiveawayContentOrThrow(): ScheduledGiveawayContent =
this as dev.inmo.tgbotapi.types.message.content.ScheduledGiveawayContent
public inline fun <T>
ResendableContent.ifScheduledGiveawayContent(block: (ScheduledGiveawayContent) -> T): T? =
scheduledGiveawayContentOrNull() ?.let(block)
public inline fun ResendableContent.stickerContentOrNull(): StickerContent? = this as?
dev.inmo.tgbotapi.types.message.content.StickerContent