add resender module

This commit is contained in:
InsanusMokrassar 2023-01-14 22:37:56 +06:00
parent c211002ac1
commit 88a89ff1e7
5 changed files with 182 additions and 1 deletions

View File

@ -13,7 +13,7 @@ kotlin_serialisation_core_version=1.4.1
github_release_plugin_version=2.4.1
tgbotapi_version=5.0.0
tgbotapi_version=5.0.1-branch_5.0.1-build1361
micro_utils_version=0.16.4
exposed_version=0.41.1
plagubot_version=3.3.0

17
resender/build.gradle Normal file
View File

@ -0,0 +1,17 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
apply from: "$mppJavaWithJsProjectPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api "dev.inmo:tgbotapi.core:$tgbotapi_version"
}
}
}
}

View File

@ -0,0 +1,18 @@
package dev.inmo.tgbotapi.libraries.resender
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import kotlinx.serialization.Serializable
@Serializable
data class MessageMetaInfo(
val chatId: IdChatIdentifier,
val messageId: MessageId,
val group: String? = null
)
operator fun MessageMetaInfo.Companion.invoke(
message: Message
) = MessageMetaInfo(message.chat.id, message.messageId, (message as? PossiblyMediaGroupMessage<*>) ?.mediaGroupId)

View File

@ -0,0 +1,144 @@
package dev.inmo.tgbotapi.libraries.resender
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.ForwardMessage
import dev.inmo.tgbotapi.requests.send.CopyMessage
import dev.inmo.tgbotapi.requests.send.media.SendMediaGroup
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.mediaCountInMediaGroup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
class MessagesResender(
private val bot: TelegramBot,
private val cacheChatId: ChatIdentifier
) {
suspend fun resend(
targetChatId: IdChatIdentifier,
messagesInfo: List<MessageMetaInfo>
): List<Pair<MessageMetaInfo, MessageMetaInfo>> {
val orders = messagesInfo.mapIndexed { i, messageInfo -> messageInfo to i }.toMap()
val sortedMessagesContents = messagesInfo.groupBy { it.group }.flatMap { (group, list) ->
if (group == null) {
list.map {
orders.getValue(it) to listOf(it)
}
} else {
listOf(orders.getValue(list.first()) to list)
}
}.sortedBy { it.first }
return sortedMessagesContents.flatMap { (_, contents) ->
val result = mutableListOf<Pair<MessageMetaInfo, MessageMetaInfo>>()
when {
contents.size == 1 -> {
val messageInfo = contents.first()
runCatching {
MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
fromChatId = messageInfo.chatId,
messageId = messageInfo.messageId
)
)
)
}.onFailure { _ ->
runCatching {
bot.execute(
ForwardMessage(
toChatId = targetChatId,
fromChatId = messageInfo.chatId,
messageId = messageInfo.messageId
)
)
}.onSuccess {
MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
fromChatId = it.chat.id,
messageId = it.messageId
)
)
)
}
}.getOrNull() ?.let {
messageInfo to it
}
}
else -> {
val resultContents = contents.mapNotNull {
it to (
bot.execute(
ForwardMessage(
toChatId = cacheChatId,
fromChatId = it.chatId,
messageId = it.messageId
)
) as? ContentMessage<*> ?: return@mapNotNull null)
}.mapNotNull { (src, forwardedMessage) ->
val forwardedMessageAsMediaPartMessage = forwardedMessage.takeIf {
it.content is MediaGroupPartContent
} ?.let {
it as ContentMessage<MediaGroupPartContent>
}
src to (forwardedMessageAsMediaPartMessage ?: null.also { _ ->
result.add(
src to MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
fromChatId = forwardedMessage.chat.id,
messageId = forwardedMessage.messageId
)
)
)
)
} ?: return@mapNotNull null)
}
resultContents.singleOrNull() ?.also { (src, it) ->
result.add(
src to MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
it.chat.id,
it.messageId
)
)
)
)
} ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach {
bot.execute(
SendMediaGroup<MediaGroupPartContent>(
targetChatId,
it.map { it.second.content.toMediaGroupMemberTelegramMedia() }
)
).content.group.mapIndexed { i, partWrapper ->
it.getOrNull(i) ?.let {
result.add(
it.first to MessageMetaInfo(
partWrapper.sourceMessage.chat.id,
partWrapper.sourceMessage.messageId,
partWrapper.sourceMessage.mediaGroupId
)
)
}
}
}
}
}
result.toList()
}
}
}

View File

@ -7,6 +7,8 @@ String[] includes = [
":cache:content:common",
":cache:content:micro_utils",
":resender",
]