Compare commits

...

52 Commits

Author SHA1 Message Date
7c6005bea3 update dependencies 2025-01-29 14:32:39 +06:00
3f6067b34e start 0.26.2 2025-01-29 14:30:21 +06:00
af72bba116 Merge pull request #84 from InsanusMokrassar/0.26.1
0.26.1
2024-11-11 16:17:26 +06:00
84f04fb1f0 Merge pull request #82 from InsanusMokrassar/renovate/configure
Configure Renovate
2024-11-11 16:15:40 +06:00
5524fc9fa0 start 0.26.1 and update dependencies 2024-11-11 16:08:08 +06:00
d0eebc0ace Merge pull request #83 from InsanusMokrassar/0.26.0
0.26.0
2024-11-04 22:23:30 +06:00
891dab1f4b fixes of build 2024-11-04 22:23:16 +06:00
9f6895a530 update dependencies 2024-11-04 22:14:39 +06:00
49084169d2 start 0.26.0 2024-11-04 22:14:09 +06:00
renovate[bot]
684172cc08 Add renovate.json 2024-10-22 10:46:07 +00:00
1457cfc748 Merge pull request #81 from InsanusMokrassar/0.25.0
0.25.0
2024-09-22 19:40:07 +06:00
6784a3c49a update plagubot 2024-09-22 18:22:07 +06:00
8ef89a32c7 Merge pull request #80 from InsanusMokrassar/0.24.0
0.24.0
2024-09-14 21:24:53 +06:00
d16de6428a start 0.24.0 2024-09-14 20:25:49 +06:00
49475a457d Merge pull request #79 from InsanusMokrassar/0.23.0
0.23.0
2024-09-06 00:16:21 +06:00
b8312873b0 start 0.23.0 && update dependencies 2024-09-06 00:14:42 +06:00
3ede07c2a6 Merge pull request #78 from InsanusMokrassar/0.22.0
0.22.0
2024-08-12 16:44:02 +06:00
a0e17a664c fix of build 2024-08-12 16:42:37 +06:00
fc3bf19453 start 0.22.0 and update dependencies 2024-08-12 16:37:18 +06:00
8d1c57700e Merge pull request #77 from InsanusMokrassar/0.21.1
0.21.1
2024-07-24 16:43:37 +06:00
00c0f0fd6f start 0.21.1 and update dependencies 2024-07-24 16:41:36 +06:00
551eb293ab Merge pull request #76 from InsanusMokrassar/0.21.0
0.21.0
2024-07-11 23:10:05 +06:00
f1b58a889f update dependencies 2024-07-11 23:08:41 +06:00
36a0f9b65b start 0.21.0 2024-07-11 23:07:47 +06:00
86abe49bc1 Merge pull request #75 from InsanusMokrassar/0.20.0
0.20.0
2024-06-27 23:27:26 +06:00
5b62bfa7d3 update dependencies 2024-06-27 23:26:52 +06:00
d94d847715 start 0.20.0 2024-06-27 23:18:23 +06:00
91013b914d Merge pull request #74 from InsanusMokrassar/0.19.0
0.19.0
2024-04-23 21:21:02 +06:00
cec4c610f3 fixes in build 2024-04-23 21:20:03 +06:00
b9003388b1 Merge pull request #73 from InsanusMokrassar/0.19.0
0.19.0
2024-04-23 18:53:32 +06:00
6d161c2d78 update dependencies 2024-04-23 18:52:47 +06:00
dc63639fee Merge pull request #72 from InsanusMokrassar/0.18.3
0.18.3
2024-02-21 02:25:50 +06:00
66934c823d revert algorithm of messages resender 2024-02-21 02:22:45 +06:00
90870c225c start 0.18.3 2024-02-21 02:00:10 +06:00
106d01775c Merge pull request #71 from InsanusMokrassar/0.18.2
0.18.2
2024-02-18 21:38:49 +06:00
cea2f7dc6e update dependencies and start 0.18.2 2024-02-18 21:37:38 +06:00
7d461edc9b Merge pull request #70 from InsanusMokrassar/0.18.1
0.18.1
2024-02-10 23:48:47 +06:00
c52c6cb633 update dependencies 2024-02-10 23:48:05 +06:00
6db1755ee7 start 0.18.1 2024-02-10 23:46:47 +06:00
ccf60c95ca Merge pull request #69 from InsanusMokrassar/0.18.0
0.18.0
2024-01-13 15:40:35 +06:00
4057d5167f improvements in MessagesResender 2024-01-13 14:37:21 +06:00
f19664da58 0.18.0 2024-01-12 20:35:48 +06:00
646a551b15 Merge pull request #68 from InsanusMokrassar/0.17.2
0.17.2
2023-12-24 23:33:45 +06:00
a08974e76d update gradle wrapper 2023-12-24 23:33:14 +06:00
30e62041c0 0.17.2 2023-12-24 23:30:19 +06:00
be8fe43e76 Merge pull request #67 from InsanusMokrassar/0.17.1
0.17.1
2023-12-10 15:04:02 +06:00
42f3a064ad update repositories 2023-12-10 14:59:50 +06:00
34f9d8c0ab 0.17.1 2023-12-10 14:56:37 +06:00
6e4fc54a23 Merge pull request #66 from InsanusMokrassar/0.17.0
0.17.0
2023-11-26 21:06:55 +06:00
674ee28991 update dependencies 2023-11-26 21:05:17 +06:00
4950fd4ed0 start 0.17.0 2023-11-26 21:04:41 +06:00
e3f5ae0b24 Merge pull request #65 from InsanusMokrassar/0.16.0
0.16.0
2023-11-06 17:37:49 +06:00
16 changed files with 87 additions and 64 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.idea
.kotlin
out/*
*.iml
target

View File

@@ -18,7 +18,7 @@ allprojects {
mavenLocal()
mavenCentral()
google()
maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" }
maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
}
}

View File

@@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.libraries.cache.admins
import korlibs.time.minutes
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.Seconds
import korlibs.time.seconds
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.serialization.Serializable

View File

@@ -8,6 +8,7 @@ import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.ExtendedBot
import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember
import dev.inmo.tgbotapi.types.message.abstracts.*
import korlibs.time.seconds
import kotlinx.serialization.Serializable
interface DefaultAdminsCacheAPIRepo {

View File

@@ -38,8 +38,8 @@ fun TelegramBot.createAdminsCacheAPI(
{ long("chatId") },
{ text("member") },
"AdminsTable"
).withMapper<IdChatIdentifier, AdministratorChatMember, Identifier, String>(
keyFromToTo = { chatId },
).withMapper<IdChatIdentifier, AdministratorChatMember, Long, String>(
keyFromToTo = { chatId.long },
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(AdministratorChatMember.serializer(), this) },
keyToToFrom = { toChatId() },
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(AdministratorChatMember.serializer(), this) }
@@ -49,8 +49,8 @@ fun TelegramBot.createAdminsCacheAPI(
{ long("chatId") },
{ long("datetime") },
"AdminsUpdatesTimesTable"
).withMapper<IdChatIdentifier, Long, Identifier, Long>(
keyFromToTo = { chatId },
).withMapper<IdChatIdentifier, Long, Long, Long>(
keyFromToTo = { chatId.long },
valueFromToTo = { this },
keyToToFrom = { toChatId() },
valueToToFrom = { this }
@@ -63,8 +63,8 @@ fun TelegramBot.createAdminsCacheAPI(
{ long("chatId") },
{ text("settings") },
"DynamicAdminsCacheSettingsAPI"
).withMapper<IdChatIdentifier, AdminsCacheSettings, Identifier, String>(
keyFromToTo = { chatId },
).withMapper<IdChatIdentifier, AdminsCacheSettings, Long, String>(
keyFromToTo = { chatId.long },
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(AdminsCacheSettings.serializer() , this) },
keyToToFrom = { toChatId() },
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(AdminsCacheSettings.serializer() , this) }

View File

@@ -4,6 +4,7 @@ import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo
import dev.inmo.micro_utils.repos.mappers.withMapper
import dev.inmo.plagubot.Plugin
import dev.inmo.plagubot.database
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DefaultAdminsCacheAPIRepoImpl
import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DynamicAdminsCacheSettingsAPI
@@ -44,7 +45,7 @@ class AdminsPlugin : Plugin {
return flow.filterNotNull().first()
}
override fun Module.setupDI(database: Database, params: JsonObject) {
override fun Module.setupDI(config: JsonObject) {
single { this@AdminsPlugin }
val scopeQualifier = named("admins plugin scope")
single(scopeQualifier) { CoroutineScope(Dispatchers.IO + SupervisorJob()) }
@@ -55,8 +56,8 @@ class AdminsPlugin : Plugin {
{ long("chatId") },
{ text("member") },
"AdminsTable"
).withMapper<IdChatIdentifier, AdministratorChatMember, Identifier, String>(
keyFromToTo = { chatId },
).withMapper<IdChatIdentifier, AdministratorChatMember, Long, String>(
keyFromToTo = { chatId.long },
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) },
keyToToFrom = { toChatId() },
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) }
@@ -66,8 +67,8 @@ class AdminsPlugin : Plugin {
{ long("chatId") },
{ long("datetime") },
"AdminsUpdatesTimesTable"
).withMapper<IdChatIdentifier, Long, Identifier, Long>(
keyFromToTo = { chatId },
).withMapper<IdChatIdentifier, Long, Long, Long>(
keyFromToTo = { chatId.long },
valueFromToTo = { this },
keyToToFrom = { toChatId() },
valueToToFrom = { this }
@@ -82,8 +83,8 @@ class AdminsPlugin : Plugin {
{ long("chatId") },
{ text("settings") },
"DynamicAdminsCacheSettingsAPI"
).withMapper<IdChatIdentifier, AdminsCacheSettings, Identifier, String>(
keyFromToTo = { chatId },
).withMapper<IdChatIdentifier, AdminsCacheSettings, Long, String>(
keyFromToTo = { chatId.long },
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) },
keyToToFrom = { toChatId() },
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) }

View File

@@ -3,8 +3,7 @@ package dev.inmo.tgbotapi.libraries.cache.media.common
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import io.ktor.utils.io.core.Input
import io.ktor.utils.io.core.copyTo
import io.ktor.utils.io.streams.asInput
import io.ktor.utils.io.streams.asOutput
import io.ktor.utils.io.streams.*
import java.io.File
class InFilesMessagesFilesCache<K>(
@@ -39,8 +38,8 @@ class InFilesMessagesFilesCache<K>(
val file = File(folderFile, fullFileName).apply {
delete()
}
inputAllocator().use { input ->
file.outputStream().asOutput().use { output ->
inputAllocator().inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}

View File

@@ -4,7 +4,7 @@ import dev.inmo.micro_utils.repos.*
import dev.inmo.micro_utils.repos.mappers.withMapper
import dev.inmo.tgbotapi.libraries.cache.media.common.MessagesSimpleCache
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.message.content.MessageContent
import kotlinx.serialization.*
import kotlinx.serialization.builtins.PairSerializer
@@ -47,7 +47,7 @@ class SimpleKeyValueMessageContentCache<K>(
val chatIdToMessageIdentifierSerializer = PairSerializer(
ChatId.serializer(),
MessageIdentifier.serializer()
MessageId.serializer()
)
val messageContentSerializer = PolymorphicSerializer<MessageContent>(MessageContent::class)
@@ -56,9 +56,9 @@ inline fun <K> KeyValueRepo<K, MessageContent>.asMessageContentCache() = SimpleK
inline fun KeyValueRepo<String, String>.asMessageContentCache(
serialFormatCreator: (SerializersModule) -> StringFormat = { Json { serializersModule = it } }
): StandardKeyValueRepo<Pair<ChatId, MessageIdentifier>, MessageContent> {
): StandardKeyValueRepo<Pair<ChatId, MessageId>, MessageContent> {
val serialFormat = serialFormatCreator(MessageContent.serializationModule())
return withMapper<Pair<ChatId, MessageIdentifier>, MessageContent, String, String>(
return withMapper<Pair<ChatId, MessageId>, MessageContent, String, String>(
{ serialFormat.encodeToString(chatIdToMessageIdentifierSerializer, this) },
{ serialFormat.encodeToString(messageContentSerializer, this) },
{ serialFormat.decodeFromString(chatIdToMessageIdentifierSerializer, this) },
@@ -70,9 +70,9 @@ inline fun KeyValueRepo<String, String>.asMessageContentCache(
@JsName("stringsKeyValueAsHexMessageContentCache")
inline fun KeyValueRepo<String, String>.asMessageContentCache(
serialFormatCreator: (SerializersModule) -> BinaryFormat
): StandardKeyValueRepo<Pair<ChatId, MessageIdentifier>, MessageContent> {
): StandardKeyValueRepo<Pair<ChatId, MessageId>, MessageContent> {
val serialFormat = serialFormatCreator(MessageContent.serializationModule())
return withMapper<Pair<ChatId, MessageIdentifier>, MessageContent, String, String>(
return withMapper<Pair<ChatId, MessageId>, MessageContent, String, String>(
{ serialFormat.encodeToHexString(chatIdToMessageIdentifierSerializer, this) },
{ serialFormat.encodeToHexString(messageContentSerializer, this) },
{ serialFormat.decodeFromHexString(chatIdToMessageIdentifierSerializer, this) },
@@ -84,9 +84,9 @@ inline fun KeyValueRepo<String, String>.asMessageContentCache(
@JsName("bytesKeyValueAsMessageContentCache")
inline fun KeyValueRepo<ByteArray, ByteArray>.asMessageContentCache(
serialFormatCreator: (SerializersModule) -> BinaryFormat
): StandardKeyValueRepo<Pair<ChatId, MessageIdentifier>, MessageContent> {
): StandardKeyValueRepo<Pair<ChatId, MessageId>, MessageContent> {
val serialFormat = serialFormatCreator(MessageContent.serializationModule())
return withMapper<Pair<ChatId, MessageIdentifier>, MessageContent, ByteArray, ByteArray>(
return withMapper<Pair<ChatId, MessageId>, MessageContent, ByteArray, ByteArray>(
{ serialFormat.encodeToByteArray(chatIdToMessageIdentifierSerializer, this) },
{ serialFormat.encodeToByteArray(messageContentSerializer, this) },
{ serialFormat.decodeFromByteArray(chatIdToMessageIdentifierSerializer, this) },

View File

@@ -6,21 +6,21 @@ kotlin.incremental=true
kotlin.incremental.js=true
kotlin_version=1.9.20
kotlin_serialisation_core_version=1.6.0
kotlin_version=2.1.10
kotlin_serialisation_core_version=1.8.0
github_release_plugin_version=2.4.1
github_release_plugin_version=2.5.2
tgbotapi_version=9.3.0
micro_utils_version=0.20.12
exposed_version=0.44.1
plagubot_version=7.3.0
tgbotapi_version=23.1.2
micro_utils_version=0.24.5
exposed_version=0.58.0
plagubot_version=10.3.1
# Dokka
dokka_version=1.9.10
dokka_version=2.0.0
# Project data
group=dev.inmo
version=0.16.0
version=0.26.2

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -37,7 +37,6 @@ kotlin {
jsTest {
dependencies {
implementation kotlin('test-js')
implementation kotlin('test-junit')
}
}
}

View File

@@ -50,18 +50,14 @@ publishing {
}
}
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
maven {
name = "Gitea"
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
name = "InmoNexus"
url = uri("https://nexus.inmo.dev/repository/maven-releases/")
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
}
authentication {
header(HttpHeaderAuthentication)
credentials {
username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
}
}

View File

@@ -1 +1 @@
{"licenses":[{"id":"MIT","title":"MIT License","url":"https://opensource.org/licenses/MIT"}],"mavenConfig":{"name":"${project.name}","description":"${project.name}","url":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries","vcsUrl":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotApiLibraries"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
{"licenses":[{"id":"MIT","title":"MIT License","url":"https://opensource.org/licenses/MIT"}],"mavenConfig":{"name":"${project.name}","description":"${project.name}","url":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries","vcsUrl":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotApiLibraries"},{"name":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}

View File

@@ -2,9 +2,12 @@ package dev.inmo.tgbotapi.libraries.resender
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MediaGroupId
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import kotlinx.serialization.Serializable
@Serializable
@@ -12,8 +15,21 @@ data class MessageMetaInfo(
@Serializable(FullChatIdentifierSerializer::class)
val chatId: IdChatIdentifier,
val messageId: MessageId,
val group: String? = null
)
val group: MediaGroupId? = null
) {
val metaInfo: Message.MetaInfo
get() = Message.MetaInfo(chatId, messageId)
}
fun Message.asMessageMetaInfos(): List<MessageMetaInfo> {
return if (this is ContentMessage<*>) {
(content as? MediaGroupContent<*>) ?.group ?.map {
MessageMetaInfo(it.sourceMessage.chat.id, it.sourceMessage.messageId, it.sourceMessage.mediaGroupId)
}
} else {
null
} ?: listOf(MessageMetaInfo(chat.id, messageId, (this as? PossiblyMediaGroupMessage<*>) ?.mediaGroupId))
}
operator fun MessageMetaInfo.Companion.invoke(
message: Message

View File

@@ -1,8 +1,11 @@
package dev.inmo.tgbotapi.libraries.resender
import dev.inmo.micro_utils.common.applyDiff
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.ForwardMessage
import dev.inmo.tgbotapi.requests.ForwardMessages
import dev.inmo.tgbotapi.requests.send.CopyMessage
import dev.inmo.tgbotapi.requests.send.CopyMessages
import dev.inmo.tgbotapi.requests.send.media.SendMediaGroup
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.IdChatIdentifier
@@ -46,9 +49,9 @@ class MessagesResender(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
toChatId = targetChatId,
fromChatId = messageInfo.chatId,
messageId = messageInfo.messageId
messageId = messageInfo.messageId,
)
)
)
@@ -66,7 +69,7 @@ class MessagesResender(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
toChatId = targetChatId,
fromChatId = it.chat.id,
messageId = it.messageId
)
@@ -80,13 +83,13 @@ class MessagesResender(
else -> {
val resultContents = contents.mapNotNull {
it to (
bot.execute(
ForwardMessage(
toChatId = cacheChatId,
fromChatId = it.chatId,
messageId = it.messageId
)
) as? ContentMessage<*> ?: return@mapNotNull null)
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
@@ -99,7 +102,7 @@ class MessagesResender(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
toChatId = targetChatId,
fromChatId = forwardedMessage.chat.id,
messageId = forwardedMessage.messageId
)
@@ -115,9 +118,9 @@ class MessagesResender(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
it.chat.id,
it.messageId
toChatId = targetChatId,
fromChatId = it.chat.id,
messageId = it.messageId
)
)
)