diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt index 5300157..5eb0a3d 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt @@ -173,7 +173,12 @@ public class SendMessageApi private constructor(body: Body) : SimpleBodyTelegram /** * @see Body.text */ - public var text: String? = null + public var text: StringBuilder? = null + + public fun text(append: CharSequence) { + val apd = text ?: StringBuilder().also { text = it } + apd.append(append) + } // Optional @@ -264,7 +269,7 @@ public class SendMessageApi private constructor(body: Body) : SimpleBodyTelegram return Body( chatId = chatId, - text = text, + text = text.toString(), messageThreadId = messageThreadId, parseMode = parseMode, entities = entities, @@ -301,6 +306,6 @@ public inline fun buildSendMessageApi( block: Builder.() -> Unit = {} ): SendMessageApi = buildSendMessageApi { this.chatId = chatId - this.text = text + this.text = StringBuilder(text) block() } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt index ab5d24e..90b1314 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt @@ -48,7 +48,7 @@ public interface TelegramChatAware { } /** - * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP].value) + * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP] or [ChatType.SUPERGROUP]) * or a channel ([Chat.type] == [ChatType.CHANNEL].value). * * @see TelegramChatGroup @@ -114,8 +114,7 @@ public interface TelegramChatGroupActor : TelegramChatAware, ChatGroup { /** - * - * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP].value). + * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP] or [ChatType.SUPERGROUP]). * * @author ForteScarlet */ diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt index 0e29455..d34d7c6 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt @@ -86,8 +86,9 @@ public interface TelegramMember : TelegramUser, Member { sendToMemberIsUnsupported() } -internal const val SEND_TO_MEMBER_IS_UNSUPPORTED = "Telegram bot cannot proactively send a message to a member " + - "because the private chat id is unknown." +internal const val SEND_TO_MEMBER_IS_UNSUPPORTED = + "Telegram bot cannot proactively send a message to a member " + + "because the private chat id is unknown." internal fun sendToMemberIsUnsupported(): Nothing = throw UnsupportedOperationException(SEND_TO_MEMBER_IS_UNSUPPORTED) diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt index fd6722f..74c4b34 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt @@ -18,7 +18,6 @@ package love.forte.simbot.component.telegram.core.actor.internal import love.forte.simbot.common.collectable.Collectable -import love.forte.simbot.common.collectable.emptyCollectable import love.forte.simbot.common.id.ID import love.forte.simbot.common.id.toInt import love.forte.simbot.component.telegram.core.actor.TelegramChatGroupActor @@ -26,14 +25,12 @@ import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.definition.Role import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent import love.forte.simbot.telegram.api.chat.GetChatMemberApi import love.forte.simbot.telegram.api.chat.GetChatMemberCountApi -import love.forte.simbot.telegram.api.message.SendMessageApi -import love.forte.simbot.telegram.stdlib.bot.requestDataBy import love.forte.simbot.telegram.type.* @@ -46,7 +43,7 @@ internal abstract class AbstractTelegramChatGroupActor : TelegramChatGroupActor abstract override val source: Chat override val roles: Collectable - get() = emptyCollectable() // TODO("Not yet implemented") + get() = TODO("Not yet implemented") override suspend fun botAsMember(): TelegramMember { return bot.queryUserInfo().toTelegramMember(bot) @@ -70,15 +67,14 @@ internal abstract class AbstractTelegramChatGroupActor : TelegramChatGroupActor } override suspend fun send(text: String): TelegramMessageReceipt { - val sent = SendMessageApi.create(ChatId(source.id), text).requestDataBy(bot.source) - return sent.toTelegramMessageReceipt(bot) + return bot.send(text, source.id) } override suspend fun send(message: Message): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(message, source.id) } override suspend fun send(messageContent: MessageContent): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(messageContent, source.id) } } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt index dda6935..4ce44c8 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt @@ -19,13 +19,10 @@ package love.forte.simbot.component.telegram.core.actor.internal import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent -import love.forte.simbot.telegram.api.message.SendMessageApi -import love.forte.simbot.telegram.stdlib.bot.requestDataBy import love.forte.simbot.telegram.type.Chat -import love.forte.simbot.telegram.type.ChatId import love.forte.simbot.telegram.type.User import kotlin.coroutines.CoroutineContext @@ -42,16 +39,15 @@ internal class TelegramUserContactImpl( override val coroutineContext: CoroutineContext = bot.subContext override suspend fun send(messageContent: MessageContent): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(messageContent, sourceChat.id) } override suspend fun send(message: Message): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(message, sourceChat.id) } override suspend fun send(text: String): TelegramMessageReceipt { - val sent = SendMessageApi.create(ChatId(sourceChat.id), text).requestDataBy(bot.source) - return sent.toTelegramMessageReceipt(bot) + return bot.send(text, sourceChat.id) } override fun toString(): String = diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt index 5cbe715..6468200 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt @@ -93,12 +93,12 @@ public interface TelegramBot : Bot { override val groupRelation: GroupRelation? - get() = null // TODO + get() = null // TODO? override val guildRelation: GuildRelation? - get() = null // TODO + get() = null // TODO? override val contactRelation: ContactRelation? - get() = null // TODO + get() = null // TODO? } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt index d8735ec..80f44a2 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt @@ -35,6 +35,7 @@ import love.forte.simbot.component.telegram.core.event.TelegramUnsupportedEvent import love.forte.simbot.component.telegram.core.event.internal.TelegramChannelMessageEventImpl import love.forte.simbot.component.telegram.core.event.internal.TelegramChatGroupMessageEventImpl import love.forte.simbot.component.telegram.core.event.internal.TelegramPrivateMessageEventImpl +import love.forte.simbot.component.telegram.core.event.internal.TelegramSuperGroupMessageEventImpl import love.forte.simbot.event.Event import love.forte.simbot.event.EventDispatcher import love.forte.simbot.event.onEachError @@ -170,8 +171,16 @@ internal fun subscribeInternalProcessor( } // supergroup? + ChatType.SUPERGROUP -> { + pushEvent( + TelegramSuperGroupMessageEventImpl( + bot = bot, + sourceEvent = context, + sourceContent = value + ) + ) + } - // TODO others else -> onMismatchUpdateEvent(name, value, update, context) } } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt index 9db4fa8..963cd8d 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt @@ -23,6 +23,7 @@ import love.forte.simbot.common.time.Timestamp import love.forte.simbot.component.telegram.core.actor.TelegramChannel import love.forte.simbot.component.telegram.core.actor.TelegramChatGroup import love.forte.simbot.component.telegram.core.actor.TelegramContact +import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.time.unixDateTimestamp @@ -76,7 +77,7 @@ public interface TelegramChatGroupMessageEvent : TelegramMessageEvent, ChatGroup get() = sourceContent.from!!.id.ID @STP - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember + override suspend fun author(): TelegramMember // TODO chat group member? @ST @@ -89,6 +90,39 @@ public interface TelegramChatGroupMessageEvent : TelegramMessageEvent, ChatGroup override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt } +/** + * An event about [Message] from a [TelegramChatGroup] (chat.type == `"supergroup"`) + * + * @author ForteScarlet + */ +public interface TelegramSuperGroupMessageEvent : TelegramMessageEvent, ChatGroupMessageEvent { + override val messageContent: TelegramMessageContent + + /** + * The [TelegramChatGroup]. + */ + @STP + override suspend fun content(): TelegramChatGroup + + /** + * The [sender][Message.from]'s [id][User.id] + */ + override val authorId: ID + get() = sourceContent.from!!.id.ID + + @STP + override suspend fun author(): TelegramMember + + @ST + override suspend fun reply(text: String): TelegramMessageReceipt + + @ST + override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt + + @ST + override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt +} + /** * An event about [Message] from a [TelegramChannel] (chat.type == `"channel"`) * @@ -110,8 +144,7 @@ public interface TelegramChannelMessageEvent : TelegramMessageEvent, ChatGroupMe get() = sourceContent.from!!.id.ID @STP - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember - // TODO chat group member? + override suspend fun author(): TelegramMember @ST override suspend fun reply(text: String): TelegramMessageReceipt diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt index 47dc4b0..c390151 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt @@ -22,17 +22,14 @@ import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.actor.internal.toTelegramChannel import love.forte.simbot.component.telegram.core.actor.internal.toTelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl -import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.event.StdlibEvent import love.forte.simbot.component.telegram.core.event.TelegramChannelMessageEvent import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl -import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.toCopyApi +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.MessageContent -import love.forte.simbot.telegram.api.message.buildSendMessageApi -import love.forte.simbot.telegram.type.ChatId +import love.forte.simbot.telegram.api.message.SendMessageApi import love.forte.simbot.telegram.type.Message import love.forte.simbot.telegram.type.ReplyParameters @@ -55,28 +52,37 @@ internal class TelegramChannelMessageEventImpl( } override suspend fun author(): TelegramMember { - // TODO from!!? check senderChat? + // TODO check senderChat? return sourceContent.from!!.toTelegramMember(bot) } override suspend fun reply(text: String): TelegramMessageReceipt { - return buildSendMessageApi(ChatId(sourceContent.chat.id), text) { + return bot.send(text, sourceContent.chat.id) { replyParameters = ReplyParameters(sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot) + } } override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { - TODO("reply(Message) Not yet implemented") + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } } override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { - if (messageContent is TelegramMessageContent) { - return messageContent.source.toCopyApi(ChatId(sourceContent.chat.id)) { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { replyParameters = ReplyParameters(messageId = sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot, sourceContent.chat.id) - } - - return reply(messageContent.messages) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) } override fun toString(): String { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt index 81ed413..5c1629a 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt @@ -27,8 +27,9 @@ import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.toCopyApi +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.MessageContent +import love.forte.simbot.telegram.api.message.SendMessageApi import love.forte.simbot.telegram.api.message.buildSendMessageApi import love.forte.simbot.telegram.type.ChatId import love.forte.simbot.telegram.type.Message @@ -63,17 +64,26 @@ internal class TelegramChatGroupMessageEventImpl( } override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { - TODO("reply(Message) Not yet implemented") + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } } override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { - if (messageContent is TelegramMessageContent) { - return messageContent.source.toCopyApi(ChatId(sourceContent.chat.id)) { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { replyParameters = ReplyParameters(messageId = sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot, sourceContent.chat.id) - } - - return reply(messageContent.messages) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) } override fun toString(): String { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt index 5690d2b..4bd51bf 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt @@ -22,12 +22,12 @@ import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.event.StdlibEvent import love.forte.simbot.component.telegram.core.event.TelegramPrivateMessageEvent -import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.toCopyApi +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.MessageContent +import love.forte.simbot.telegram.api.message.SendMessageApi import love.forte.simbot.telegram.api.message.buildSendMessageApi import love.forte.simbot.telegram.type.ChatId import love.forte.simbot.telegram.type.Message @@ -57,17 +57,26 @@ internal class TelegramPrivateMessageEventImpl( } override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { - TODO("reply(Message) Not yet implemented") + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } } override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { - if (messageContent is TelegramMessageContent) { - return messageContent.source.toCopyApi(ChatId(sourceContent.chat.id)) { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { replyParameters = ReplyParameters(messageId = sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot, sourceContent.chat.id) - } - - return reply(messageContent.messages) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) } override fun toString(): String { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt new file mode 100644 index 0000000..b33f016 --- /dev/null +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024. ForteScarlet. + * + * This file is part of simbot-component-telegram. + * + * simbot-component-telegram is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-telegram is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-telegram. + * If not, see . + */ + +package love.forte.simbot.component.telegram.core.event.internal + +import love.forte.simbot.component.telegram.core.actor.internal.toTelegramChatGroup +import love.forte.simbot.component.telegram.core.actor.internal.toTelegramMember +import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl +import love.forte.simbot.component.telegram.core.bot.requestDataBy +import love.forte.simbot.component.telegram.core.event.StdlibEvent +import love.forte.simbot.component.telegram.core.event.TelegramChatGroupMessageEvent +import love.forte.simbot.component.telegram.core.message.TelegramMessageContent +import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl +import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.send +import love.forte.simbot.message.MessageContent +import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.telegram.api.message.buildSendMessageApi +import love.forte.simbot.telegram.type.ChatId +import love.forte.simbot.telegram.type.Message +import love.forte.simbot.telegram.type.ReplyParameters + + +/** + * + * @author ForteScarlet + */ +internal class TelegramSuperGroupMessageEventImpl( + override val bot: TelegramBotImpl, + override val sourceEvent: StdlibEvent, + // 记得确保 chat.type == SUPERGROUP + override val sourceContent: Message +) : TelegramChatGroupMessageEvent { + override val messageContent: TelegramMessageContent = TelegramMessageContentImpl(bot, sourceContent) + + override suspend fun content(): love.forte.simbot.component.telegram.core.actor.TelegramChatGroup { + return sourceContent.chat.toTelegramChatGroup(bot) + } + + override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember { + // TODO from!!? check senderChat? + return sourceContent.from!!.toTelegramMember(bot) + } + + override suspend fun reply(text: String): TelegramMessageReceipt { + return buildSendMessageApi(ChatId(sourceContent.chat.id), text) { + replyParameters = ReplyParameters(sourceContent.messageId) + }.requestDataBy(bot).toTelegramMessageReceipt(bot) + } + + override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + } + + override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { + replyParameters = ReplyParameters(messageId = sourceContent.messageId) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) + } + + override fun toString(): String { + return "TelegramSuperGroupMessageEvent(name=${sourceEvent.name})" + } +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt index 49be819..6018343 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt @@ -19,6 +19,7 @@ package love.forte.simbot.component.telegram.core.message import love.forte.simbot.common.id.IntID import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.common.id.LongID import love.forte.simbot.message.AggregatedMessageReceipt import love.forte.simbot.message.MessageReceipt import love.forte.simbot.message.SingleMessageReceipt @@ -34,6 +35,7 @@ public interface TelegramMessageSourceAware { public abstract class TelegramSingleMessageReceipt : TelegramMessageReceipt, SingleMessageReceipt() { abstract override val id: IntID + public abstract val chatId: LongID } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt index f333a5b..660ff98 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt @@ -19,10 +19,16 @@ package love.forte.simbot.component.telegram.core.message -import love.forte.simbot.message.Message +import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl +import love.forte.simbot.component.telegram.core.bot.requestDataBy +import love.forte.simbot.component.telegram.core.message.internal.PlainTextResolver +import love.forte.simbot.component.telegram.core.message.internal.TelegramAggregatedMessageIdReceiptImpl +import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.message.* import love.forte.simbot.telegram.api.TelegramApi import love.forte.simbot.telegram.api.message.* import love.forte.simbot.telegram.type.ChatId +import love.forte.simbot.telegram.type.MessageId import kotlin.jvm.JvmName import love.forte.simbot.telegram.type.Message as StdlibMessage @@ -45,27 +51,215 @@ internal inline fun StdlibMessage.toForwardApi( } } -internal inline fun Message.resolve() { - TODO("Message.resolve") +internal suspend inline fun TelegramBotImpl.send( + text: String, + chatId: Long, + block: SendMessageApi.Builder.() -> Unit = {} +): TelegramMessageReceipt { + return buildSendMessageApi(ChatId(chatId), text, block) + .requestDataBy(this) + .toTelegramMessageReceipt(this) } +internal suspend inline fun TelegramBotImpl.send( + messageContent: MessageContent, chatId: Long, + crossinline copyApiBlock: CopyMessageApi.Builder.() -> Unit = {}, + crossinline builderFactory: BuilderFactory = { SendMessageApi.builder() } +): TelegramMessageReceipt { + if (messageContent is TelegramMessageContent) { + return messageContent.source.toCopyApi(ChatId(chatId), copyApiBlock) + .requestDataBy(this) + .toTelegramMessageReceipt(this, chatId) + } + + return send(messageContent.messages, chatId) { builderFactory() } +} + +internal suspend fun TelegramBotImpl.send( + message: Message, + chatId: Long, + builderFactory: BuilderFactory = DefaultBuilderFactory +): TelegramMessageReceipt { + val funcList = message.resolve(builderFactory) + + fun toReceipt(result: Any): TelegramSingleMessageReceipt { + return when (result) { + is StdlibMessage -> result.toTelegramMessageReceipt(this) + is MessageId -> result.toTelegramMessageReceipt(this, chatId) + else -> error("Unexpected result type: $result") + } + } + + when { + funcList.isEmpty() -> error("Nothing to send, the message element list is empty.") + funcList.size == 1 -> { + val result = funcList.first()().requestDataBy(this) + return when (result) { + is StdlibMessage -> toReceipt(result) + is MessageId -> toReceipt(result) + else -> error("Unexpected result type: $result") + } + } + + else -> { + // 00 -> nothing, 不可能到这儿 + // 01 -> only Message + // 10 -> only MessageId + // 11 -> 混杂的 + var messageTypeMark = 0 + val resultList = funcList.map { + val result = it.invoke().requestDataBy(this) + when (result) { + is StdlibMessage -> messageTypeMark = messageTypeMark or MESSAGE_MARK + is MessageId -> messageTypeMark = messageTypeMark or MESSAGE_ID_MARK + } + result + } + + return when (messageTypeMark) { + // only Message + MESSAGE_MARK -> { + @Suppress("UNCHECKED_CAST") + val sourceList = resultList as List + return sourceList.toTelegramMessageReceipt(this, chatId) + } + // only MessageId + MESSAGE_ID_MARK -> { + @Suppress("UNCHECKED_CAST") + val idList = resultList as List + idList.toTelegramMessageReceipt(this, chatId) + } + + MESSAGE_ALL_MARK -> { + val messageIds = resultList.map { + when (it) { + is StdlibMessage -> it.messageId + is MessageId -> it.messageId + else -> error("Unexpected result type: $it") + } + } + + TelegramAggregatedMessageIdReceiptImpl(this, chatId, messageIds) + } + + else -> error("Unexpected mark value: $messageTypeMark") + } + } + } +} + +private const val MESSAGE_MARK = 0b01 +private const val MESSAGE_ID_MARK = 0b10 +private const val MESSAGE_ALL_MARK = MESSAGE_MARK or MESSAGE_ID_MARK + +internal suspend fun Message.resolve( + builderFactory: BuilderFactory = DefaultBuilderFactory +): List { + return when (val m = this) { + is Message.Element -> { + val context = SendingMessageResolverContext(builderFactory) + for (resolver in sendingResolvers) { + resolver.resolve(0, m, this, context) + } + + context.end() + } + + is Messages -> { + if (m.isEmpty()) { + return emptyList() + } + + val context = SendingMessageResolverContext(builderFactory) + m.forEachIndexed { index, element -> + for (resolver in sendingResolvers) { + resolver.resolve(index, element, this, context) + } + } + + context.end() + } + } +} + +internal fun interface SendingMessageResolver { + suspend fun resolve( + index: Int, + element: Message.Element, + source: Message, + context: SendingMessageResolverContext + ) +} + +private val sendingResolvers = listOf( + PlainTextResolver, + TelegramMessageResultApiElementSendingResolver, +) + +internal typealias BuilderFactory = () -> SendMessageApi.Builder + +internal val DefaultBuilderFactory: BuilderFactory = { SendMessageApi.builder() } + +internal typealias SendingMessageResolvedFunction = () -> TelegramApi<*> // * 只能是 Message 或 MessageId + +internal class SendingMessageResolverContext( + private val builderFactory: BuilderFactory, +) { + val apiStacks = mutableListOf() // TelegramApi? + private var _builder: SendMessageApi.Builder? = null + + fun addToStackMsg(api: () -> TelegramApi) { + apiStacks.add(api) + } + + fun addToStackMsgId(api: () -> TelegramApi) { + apiStacks.add(api) + } -internal class MessageResolver { - private val apiStacks = mutableListOf>() // TelegramApi? - var builder: SendMessageApi.Builder = SendMessageApi.builder() - private set + val builderOrNull: SendMessageApi.Builder? + get() = _builder + + /** + * 如果当前builder存在,记录并消除。 + */ + fun archiveCurrent() { + _builder?.also { b -> + apiStacks.add { b.build() } + _builder = null + } + } + + private val builderOrNew: SendMessageApi.Builder + get() = _builder ?: builderFactory().also { _builder = it } + + val builder: SendMessageApi.Builder + get() = builderOrNew fun newBuilder(): SendMessageApi.Builder { - apiStacks.add(builder.build()) - return SendMessageApi.builder().also { builder = it } + archiveCurrent() + return builderFactory().also { _builder = it } } - inline fun checkOrNewBuilder(block: (SendMessageApi.Builder) -> Boolean): SendMessageApi.Builder { - val currentBuilder = builder - return if (block(currentBuilder)) { - currentBuilder + inline fun builderOrNew(createNew: (SendMessageApi.Builder) -> Boolean): SendMessageApi.Builder { + val current = builderOrNew + return if (createNew(current)) { + newBuilder() } else { + current + } + } + + inline fun builderOrNullOrNew(createNew: (SendMessageApi.Builder?) -> Boolean): SendMessageApi.Builder? { + val current = builderOrNull + return if (createNew(builderOrNull)) { newBuilder() + } else { + current } } + + fun end(): List { + archiveCurrent() + return apiStacks + } } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt new file mode 100644 index 0000000..6629769 --- /dev/null +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024. ForteScarlet. + * + * This file is part of simbot-component-telegram. + * + * simbot-component-telegram is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-telegram is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-telegram. + * If not, see . + */ + +package love.forte.simbot.component.telegram.core.message + +import love.forte.simbot.telegram.api.TelegramApi +import love.forte.simbot.telegram.api.message.CopyMessageApi +import love.forte.simbot.telegram.api.message.ForwardMessageApi +import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.telegram.type.Message +import love.forte.simbot.telegram.type.MessageId +import kotlin.jvm.JvmStatic + + +/** + * A [TelegramMessageElement] implementation that provide a [TelegramApi] + * (witch the type of result is [Message] or [MessageId], + * e.g. [SendMessageApi], [ForwardMessageApi], [CopyMessageApi], etc.) directly. + * + * [TelegramMessageResultApiElement] is a [SendOnly] type, + * and it is also a 'malleable' best message element. + * + * Note: The [TelegramMessageResultApiElement] is NOT serializable. + * @author ForteScarlet + */ +@SendOnly +public sealed class TelegramMessageResultApiElement : TelegramMessageElement { + /** + * The result `*` is [Message] or [MessageId]. + */ + public abstract val api: TelegramApi<*> + + public companion object { + /** + * Create a [TelegramMessageResultApiElement] by [api]. + */ + @JvmStatic + public fun createByMessageApi(api: TelegramApi): TelegramMessageResultApiElement = + MessageResult(api) + + /** + * Create a [TelegramMessageResultApiElement] by [api]. + */ + @JvmStatic + public fun createByMessageIdApi(api: TelegramApi): TelegramMessageResultApiElement = + MessageIdResult(api) + } +} + +internal data class MessageResult(override val api: TelegramApi) : TelegramMessageResultApiElement() +internal data class MessageIdResult(override val api: TelegramApi) : TelegramMessageResultApiElement() + + +internal object TelegramMessageResultApiElementSendingResolver : SendingMessageResolver { + override suspend fun resolve( + index: Int, + element: love.forte.simbot.message.Message.Element, + source: love.forte.simbot.message.Message, + context: SendingMessageResolverContext + ) { + if (element is TelegramMessageResultApiElement) { + context.archiveCurrent() + when (element) { + is MessageIdResult -> { + context.addToStackMsgId { element.api } + } + is MessageResult -> { + context.addToStackMsg { element.api } + } + } + } + } +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt new file mode 100644 index 0000000..609678c --- /dev/null +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024. ForteScarlet. + * + * This file is part of simbot-component-telegram. + * + * simbot-component-telegram is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-telegram is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-telegram. + * If not, see . + */ + +package love.forte.simbot.component.telegram.core.message.internal + +import love.forte.simbot.component.telegram.core.message.StdlibMessage +import love.forte.simbot.message.Messages +import love.forte.simbot.message.MessagesBuilder + +/** + * + */ +internal fun StdlibMessage.toMessages(): Messages { + val builder = MessagesBuilder.create() + // TODO forwardOrigin: MessageOrigin? + // TODO replyToMessage: Message ..? + // TODO externalReply: ExternalReplyInfo ..? + // TODO quote: TextQuote + // TODO replyToStory: Story ..? + // TODO hasProtectedContent: Boolean ..? + + text?.also { builder.add(it) } + + // TODO entities ..? + + // TODO linkPreviewOptions: LinkPreviewOptions + // TODO animation: Animation + // TODO audio: Audio + // TODO document: Document + // TODO photo: List + // TODO sticker: Sticker + // TODO story: Story + // TODO video: Video + // TODO videoNote: VideoNote + // TODO voice: Voice + // TODO voice: Voice + // TODO - caption: String? = null, + // - captionEntities: List? = null, + + // TODO contact: Contact + // TODO dice: Dice + // TODO game: Game + // TODO poll: Poll + // TODO venue: Venue + // TODO location: Location + + return builder.build() +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageApiBodyElement.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/SendingMessageStandardResolvers.kt similarity index 50% rename from simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageApiBodyElement.kt rename to simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/SendingMessageStandardResolvers.kt index c94aa5d..37ab565 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageApiBodyElement.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/SendingMessageStandardResolvers.kt @@ -15,25 +15,23 @@ * If not, see . */ -package love.forte.simbot.component.telegram.core.message +package love.forte.simbot.component.telegram.core.message.internal -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.component.telegram.core.message.SendingMessageResolver +import love.forte.simbot.component.telegram.core.message.SendingMessageResolverContext +import love.forte.simbot.message.Message +import love.forte.simbot.message.PlainText - -/** - * - * A [TelegramMessageElement] implementation that provide a [SendMessageApi.Body] directly. - * [body] is sent directly as a separate SendApi and is not affected by other elements. - * - * [TelegramMessageApiBodyElement] is a type used only when sending, and it is also a 'malleable' best message element. - * - * A [SendOnly] element, will not be received in event. - * - * @author ForteScarlet - */ -@SendOnly -@Serializable -@SerialName("telegram.m.message_api_body") -public data class TelegramMessageApiBodyElement(public val body: SendMessageApi.Body) : TelegramMessageElement +internal object PlainTextResolver : SendingMessageResolver { + override suspend fun resolve( + index: Int, + element: Message.Element, + source: Message, + context: SendingMessageResolverContext + ) { + if (element is PlainText) { + context.builder.text(element.text) + } + // TODO TelegramText? (can with parse mode option) + } +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt index e3a8005..f98d2ca 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt @@ -25,7 +25,6 @@ import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.message.StdlibMessage import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.message.Messages -import love.forte.simbot.message.emptyMessages import love.forte.simbot.telegram.api.message.DeleteMessageApi import love.forte.simbot.telegram.type.ChatId @@ -39,11 +38,12 @@ internal class TelegramMessageContentImpl( override val source: StdlibMessage ) : TelegramMessageContent { - override val messages: Messages - get() = emptyMessages() // TODO("Not yet implemented") + override val messages: Messages by lazy { + source.toMessages() + } override val plainText: String? - get() = source.text // TODO entries? + get() = source.text override suspend fun delete(vararg options: DeleteOption) { kotlin.runCatching { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt index d39110c..0f7c2de 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt @@ -21,6 +21,8 @@ import love.forte.simbot.ability.DeleteFailureException import love.forte.simbot.ability.DeleteOption import love.forte.simbot.common.id.IntID import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.common.id.LongID +import love.forte.simbot.common.id.LongID.Companion.ID import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.message.* import love.forte.simbot.telegram.api.message.DeleteMessageApi @@ -39,6 +41,8 @@ internal class TelegramSingleMessageSourceReceiptImpl( private val bot: TelegramBotImpl, override val message: Message ) : TelegramSingleMessageSourceReceipt() { + override val chatId: LongID + get() = message.chat.id.ID override suspend fun delete(vararg options: DeleteOption) { // TODO option ignore fail @@ -71,15 +75,18 @@ internal class TelegramSingleMessageSourceReceiptImpl( */ internal class TelegramSingleMessageIdReceiptImpl( private val bot: TelegramBotImpl, - private val chatId: Long, + private val chatIdValue: Long, private val messageId: Int ) : TelegramSingleMessageIdReceipt() { override val id: IntID get() = messageId.ID + override val chatId: LongID + get() = chatIdValue.ID + override suspend fun delete(vararg options: DeleteOption) { // TODO option ignore fail - DeleteMessageApi.create(ChatId(chatId), messageId).requestDataBy(bot.source) + DeleteMessageApi.create(ChatId(chatIdValue), messageId).requestDataBy(bot.source) } @@ -105,6 +112,19 @@ internal class TelegramSingleMessageIdReceiptImpl( } } +// internal class SimpleTelegramAggregatedMessageReceiptImpl( +// private val bot: TelegramBotImpl, +// private val chatId: Long, +// private val receipts: List, +// ) : TelegramAggregatedMessageReceipt() { +// override val ids: Collection +// get() = receipts.map { it.id } +// +// override fun get(index: Int): TelegramSingleMessageReceipt = receipts[index] +// +// override fun iterator(): Iterator = receipts.iterator() +// } + internal class TelegramAggregatedMessageIdReceiptImpl( private val bot: TelegramBotImpl, private val chatId: Long, @@ -178,6 +198,7 @@ internal fun MessageId.toTelegramMessageReceipt( ): TelegramSingleMessageIdReceiptImpl = TelegramSingleMessageIdReceiptImpl(bot, chatId, messageId) + /** * [this] must be >= 1 * (preferably >= 2).