diff --git a/BoostsInfoBot/README.md b/BoostsInfoBot/README.md
new file mode 100644
index 0000000..d03cbab
--- /dev/null
+++ b/BoostsInfoBot/README.md
@@ -0,0 +1,9 @@
+# UserChatShared
+
+Showing info about boosts
+
+## Launch
+
+```bash
+../gradlew run --args="BOT_TOKEN"
+```
diff --git a/BoostsInfoBot/build.gradle b/BoostsInfoBot/build.gradle
new file mode 100644
index 0000000..abef9c9
--- /dev/null
+++ b/BoostsInfoBot/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+apply plugin: 'kotlin'
+apply plugin: 'application'
+
+mainClassName="BoostsInfoKt"
+
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+
+    implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
+}
diff --git a/BoostsInfoBot/src/main/kotlin/BoostsInfo.kt b/BoostsInfoBot/src/main/kotlin/BoostsInfo.kt
new file mode 100644
index 0000000..fd7f058
--- /dev/null
+++ b/BoostsInfoBot/src/main/kotlin/BoostsInfo.kt
@@ -0,0 +1,65 @@
+import dev.inmo.kslog.common.KSLog
+import dev.inmo.kslog.common.LogLevel
+import dev.inmo.kslog.common.defaultMessageFormatter
+import dev.inmo.kslog.common.setDefaultKSLog
+import dev.inmo.tgbotapi.bot.ktor.telegramBot
+import dev.inmo.tgbotapi.extensions.api.get.getUserChatBoosts
+import dev.inmo.tgbotapi.extensions.api.send.*
+import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatBoostUpdated
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatShared
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
+import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
+import dev.inmo.tgbotapi.types.chat.member.ChatCommonAdministratorRights
+import dev.inmo.tgbotapi.types.request.RequestId
+import dev.inmo.tgbotapi.utils.regular
+import korlibs.time.DateFormat
+import korlibs.time.format
+
+suspend fun main(args: Array<String>) {
+    val isDebug = args.getOrNull(1) == "debug"
+
+    if (isDebug) {
+        setDefaultKSLog(
+            KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
+                println(defaultMessageFormatter(level, tag, message, throwable))
+            }
+        )
+    }
+
+    val requestChatId = RequestId(1)
+
+    val bot = telegramBot(args.first())
+
+    bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) {
+        onChatBoostUpdated {
+            println(it)
+        }
+
+        onCommand("start") {
+            reply(
+                it,
+                replyMarkup = flatReplyKeyboard {
+                    requestChannelButton(
+                        "Click me :)",
+                        requestChatId,
+                        botIsMember = true
+                    )
+                }
+            ) {
+                regular("Select chat to get know about your boosts")
+            }
+        }
+
+        onChatShared(initialFilter = { it.chatEvent.requestId == requestChatId }) {
+            val boosts = getUserChatBoosts(it.chatEvent.chatId, it.chat.id)
+            reply(
+                it
+            ) {
+                boosts.boosts.forEach {
+                    regular("Boost added: ${DateFormat.FORMAT1.format(it.addDate.asDate)}; Boost expire: ${DateFormat.FORMAT1.format(it.expirationDate.asDate)}; Unformatted: $it") + "\n"
+                }
+            }
+        }
+    }.join()
+}
diff --git a/GetMeBot/src/main/kotlin/GetMeBot.kt b/GetMeBot/src/main/kotlin/GetMeBot.kt
index c5917cd..460b48c 100644
--- a/GetMeBot/src/main/kotlin/GetMeBot.kt
+++ b/GetMeBot/src/main/kotlin/GetMeBot.kt
@@ -5,6 +5,7 @@ import dev.inmo.kslog.common.filter.filtered
 import dev.inmo.kslog.common.setDefaultKSLog
 import dev.inmo.tgbotapi.bot.ktor.telegramBot
 import dev.inmo.tgbotapi.extensions.api.bot.getMe
+import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
 import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
 
 /**
@@ -12,13 +13,19 @@ import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
  */
 suspend fun main(vararg args: String) {
     val botToken = args.first()
+    val isDebug = args.getOrNull(1) == "debug"
+
+    if (isDebug) {
+        setDefaultKSLog(
+            KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
+                println(defaultMessageFormatter(level, tag, message, throwable))
+            }
+        )
+    }
 
-    setDefaultKSLog(
-        KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
-            println(defaultMessageFormatter(level, tag, message, throwable))
-        }
-    )
     val bot = telegramBot(botToken)
 
-    println(bot.getMe())
+    val me = bot.getMe()
+    println(me)
+    println(bot.getChat(me))
 }
diff --git a/LinkPreviewsBot/README.md b/LinkPreviewsBot/README.md
new file mode 100644
index 0000000..c5ae135
--- /dev/null
+++ b/LinkPreviewsBot/README.md
@@ -0,0 +1,9 @@
+# ReactionsInfoBot
+
+This bot will resend messages with links with all variants of `LinkPreviewOptions`
+
+## Launch
+
+```bash
+../gradlew run --args="BOT_TOKEN"
+```
diff --git a/LinkPreviewsBot/build.gradle b/LinkPreviewsBot/build.gradle
new file mode 100644
index 0000000..a699082
--- /dev/null
+++ b/LinkPreviewsBot/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+apply plugin: 'kotlin'
+apply plugin: 'application'
+
+mainClassName="LinkPreviewsBotKt"
+
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+
+    implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
+}
diff --git a/LinkPreviewsBot/src/main/kotlin/LinkPreviewsBot.kt b/LinkPreviewsBot/src/main/kotlin/LinkPreviewsBot.kt
new file mode 100644
index 0000000..cc85073
--- /dev/null
+++ b/LinkPreviewsBot/src/main/kotlin/LinkPreviewsBot.kt
@@ -0,0 +1,93 @@
+import dev.inmo.kslog.common.KSLog
+import dev.inmo.kslog.common.LogLevel
+import dev.inmo.kslog.common.defaultMessageFormatter
+import dev.inmo.kslog.common.setDefaultKSLog
+import dev.inmo.tgbotapi.bot.ktor.telegramBot
+import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
+import dev.inmo.tgbotapi.extensions.api.send.copyMessage
+import dev.inmo.tgbotapi.extensions.api.send.reply
+import dev.inmo.tgbotapi.extensions.api.send.send
+import dev.inmo.tgbotapi.extensions.api.send.setMessageReaction
+import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMessageReactionUpdatedByUser
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMessageReactionsCountUpdated
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
+import dev.inmo.tgbotapi.extensions.utils.textLinkTextSourceOrNull
+import dev.inmo.tgbotapi.extensions.utils.uRLTextSourceOrNull
+import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
+import dev.inmo.tgbotapi.types.LinkPreviewOptions
+import dev.inmo.tgbotapi.types.chat.ExtendedChat
+import dev.inmo.tgbotapi.types.message.content.TextContent
+import dev.inmo.tgbotapi.types.message.content.TextedContent
+import dev.inmo.tgbotapi.types.reactions.Reaction
+import dev.inmo.tgbotapi.utils.customEmoji
+import dev.inmo.tgbotapi.utils.regular
+
+/**
+ * This bot will reply with the same
+ */
+suspend fun main(vararg args: String) {
+    val botToken = args.first()
+    val isDebug = args.getOrNull(1) == "debug"
+
+    if (isDebug) {
+        setDefaultKSLog(
+            KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
+                println(defaultMessageFormatter(level, tag, message, throwable))
+            }
+        )
+    }
+
+    val bot = telegramBot(botToken)
+
+    bot.buildBehaviourWithLongPolling {
+        onContentMessage {
+            val url = it.withContentOrNull<TextedContent>() ?.let {
+                it.content.textSources.firstNotNullOfOrNull {
+                    it.textLinkTextSourceOrNull() ?.url ?: it.uRLTextSourceOrNull() ?.source
+                }
+            } ?: null.apply {
+                reply(it) {
+                    regular("I am support only content with text contains url only")
+                }
+            } ?: return@onContentMessage
+            it.withContentOrNull<TextedContent>() ?.let {
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Disabled
+                )
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Large(url, showAboveText = true)
+                )
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Large(url, showAboveText = false)
+                )
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Small(url, showAboveText = true)
+                )
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Small(url, showAboveText = false)
+                )
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Default(url, showAboveText = true)
+                )
+                send(
+                    it.chat,
+                    it.content.textSources,
+                    linkPreviewOptions = LinkPreviewOptions.Default(url, showAboveText = false)
+                )
+            }
+        }
+    }.join()
+}
diff --git a/PollsBot/src/main/kotlin/PollsBot.kt b/PollsBot/src/main/kotlin/PollsBot.kt
index f489fc4..1587ecc 100644
--- a/PollsBot/src/main/kotlin/PollsBot.kt
+++ b/PollsBot/src/main/kotlin/PollsBot.kt
@@ -14,6 +14,7 @@ import dev.inmo.tgbotapi.extensions.utils.ifFromChannelGroupContentMessage
 import dev.inmo.tgbotapi.types.ChatId
 import dev.inmo.tgbotapi.types.IdChatIdentifier
 import dev.inmo.tgbotapi.types.PollIdentifier
+import dev.inmo.tgbotapi.types.ReplyParameters
 import dev.inmo.tgbotapi.types.chat.*
 import dev.inmo.tgbotapi.types.chat.GroupChat
 import dev.inmo.tgbotapi.types.chat.PrivateChat
@@ -54,7 +55,7 @@ suspend fun main(vararg args: String) {
                     it.toString()
                 },
                 isAnonymous = true,
-                replyToMessageId = it.messageId
+                replyParameters = ReplyParameters(it)
             )
             pollToChatMutex.withLock {
                 pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
@@ -69,7 +70,7 @@ suspend fun main(vararg args: String) {
                     it.toString()
                 },
                 isAnonymous = false,
-                replyToMessageId = it.messageId
+                replyParameters = ReplyParameters(it)
             )
             pollToChatMutex.withLock {
                 pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
diff --git a/ReactionsInfoBot/README.md b/ReactionsInfoBot/README.md
new file mode 100644
index 0000000..72b17bf
--- /dev/null
+++ b/ReactionsInfoBot/README.md
@@ -0,0 +1,9 @@
+# ReactionsInfoBot
+
+This bot will send info about user reactions in his PM with reply to message user reacted to
+
+## Launch
+
+```bash
+../gradlew run --args="BOT_TOKEN"
+```
diff --git a/ReactionsInfoBot/build.gradle b/ReactionsInfoBot/build.gradle
new file mode 100644
index 0000000..f0554ac
--- /dev/null
+++ b/ReactionsInfoBot/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+apply plugin: 'kotlin'
+apply plugin: 'application'
+
+mainClassName="ReactionsInfoBotKt"
+
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+
+    implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
+}
diff --git a/ReactionsInfoBot/src/main/kotlin/ReactionsInfoBot.kt b/ReactionsInfoBot/src/main/kotlin/ReactionsInfoBot.kt
new file mode 100644
index 0000000..7bfe094
--- /dev/null
+++ b/ReactionsInfoBot/src/main/kotlin/ReactionsInfoBot.kt
@@ -0,0 +1,68 @@
+import dev.inmo.kslog.common.KSLog
+import dev.inmo.kslog.common.LogLevel
+import dev.inmo.kslog.common.defaultMessageFormatter
+import dev.inmo.kslog.common.setDefaultKSLog
+import dev.inmo.tgbotapi.bot.ktor.telegramBot
+import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
+import dev.inmo.tgbotapi.extensions.api.send.reply
+import dev.inmo.tgbotapi.extensions.api.send.setMessageReaction
+import dev.inmo.tgbotapi.extensions.api.send.setMessageReactions
+import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMessageReactionUpdatedByUser
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMessageReactionsCountUpdated
+import dev.inmo.tgbotapi.types.chat.ExtendedChat
+import dev.inmo.tgbotapi.types.reactions.Reaction
+import dev.inmo.tgbotapi.utils.customEmoji
+import dev.inmo.tgbotapi.utils.regular
+
+/**
+ * This bot will send info about user reactions in his PM with reply to message user reacted to
+ */
+suspend fun main(vararg args: String) {
+    val botToken = args.first()
+    val isDebug = args.getOrNull(1) == "debug"
+
+    if (isDebug) {
+        setDefaultKSLog(
+            KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
+                println(defaultMessageFormatter(level, tag, message, throwable))
+            }
+        )
+    }
+
+    val bot = telegramBot(botToken)
+
+    bot.buildBehaviourWithLongPolling {
+        onChatMessageReactionUpdatedByUser {
+            setMessageReaction(
+                it.chat.id,
+                it.messageId,
+                "✍"
+            )
+            val replyResult = reply(
+                it.chat.id,
+                it.messageId,
+                replyInChatId = it.reactedUser.id
+            ) {
+                regular("Current reactions for message in reply:\n")
+                it.new.forEach {
+                    when (it) {
+                        is Reaction.CustomEmoji -> regular("• ") + customEmoji(it.customEmojiId) + regular("(customEmojiId: ${it.customEmojiId})")
+                        is Reaction.Emoji -> regular("• ${it.emoji}")
+                        is Reaction.Unknown -> regular("• Unknown emoji ($it)")
+                    }
+                    regular("\n")
+                }
+            }
+            setMessageReaction(
+                it.chat.id,
+                it.messageId,
+            )
+        }
+        onChatMessageReactionsCountUpdated {
+            val extendedChat: ExtendedChat = getChat(it.chat)
+            println(extendedChat)
+            println(it)
+        }
+    }.join()
+}
diff --git a/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt b/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt
index fe604d8..52e566c 100644
--- a/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt
+++ b/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt
@@ -8,6 +8,10 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilte
 import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
 import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
+import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
+import dev.inmo.tgbotapi.types.ReplyParameters
+import dev.inmo.tgbotapi.types.message.content.TextContent
+import dev.inmo.tgbotapi.types.quoteEntitiesField
 import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull
 import kotlinx.coroutines.*
 
@@ -26,7 +30,14 @@ suspend fun activateResenderBot(
                     it.content.createResend(
                         chat.id,
                         messageThreadId = it.threadIdOrNull,
-                        replyToMessageId = it.messageId
+                        replyParameters = it.replyInfo ?.messageMeta ?.let { meta ->
+                            val quote = it.withContentOrNull<TextContent>() ?.content ?.quote
+                            ReplyParameters(
+                                meta,
+                                entities = quote ?.textSources ?: emptyList(),
+                                quotePosition = quote ?.position
+                            )
+                        }
                     )
                 ) {
                     it.forEach(print)
diff --git a/RightsChangerBot/src/main/kotlin/RightsChanger.kt b/RightsChangerBot/src/main/kotlin/RightsChanger.kt
index 5245696..a2be7ef 100644
--- a/RightsChangerBot/src/main/kotlin/RightsChanger.kt
+++ b/RightsChangerBot/src/main/kotlin/RightsChanger.kt
@@ -24,6 +24,7 @@ import dev.inmo.tgbotapi.types.chat.ChatPermissions
 import dev.inmo.tgbotapi.types.chat.PublicChat
 import dev.inmo.tgbotapi.types.chat.member.*
 import dev.inmo.tgbotapi.types.commands.BotCommandScope
+import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage
 import dev.inmo.tgbotapi.types.request.RequestId
 import dev.inmo.tgbotapi.utils.*
 import dev.inmo.tgbotapi.utils.mention
@@ -185,14 +186,21 @@ suspend fun main(args: Array<String>) {
     ) {
         onCommand(
             "simple",
-            initialFilter = { it.chat is PublicChat && it.fromUserMessageOrNull()?.user?.id == allowedAdmin }) {
+            initialFilter = { it.chat is PublicChat && it.fromUserMessageOrNull()?.user?.id == allowedAdmin }
+        ) {
             val replyMessage = it.replyTo
             val userInReply = replyMessage?.fromUserMessageOrNull()?.user?.id ?: return@onCommand
-            reply(
-                replyMessage,
-                "Manage keyboard:",
-                replyMarkup = buildCommonKeyboard(it.chat.id.toChatId(), userInReply) ?: return@onCommand
-            )
+            if (replyMessage is AccessibleMessage) {
+                reply(
+                    replyMessage,
+                    "Manage keyboard:",
+                    replyMarkup = buildCommonKeyboard(it.chat.id.toChatId(), userInReply) ?: return@onCommand
+                )
+            } else {
+                reply(it) {
+                    regular("Reply to somebody's message to get hist/her rights keyboard")
+                }
+            }
         }
         onCommand(
             "granular",
@@ -204,11 +212,17 @@ suspend fun main(args: Array<String>) {
             val usernameInText = it.content.textSources.firstNotNullOfOrNull { it.mentionTextSourceOrNull() } ?.username
             val userInReply = replyMessage?.fromUserMessageOrNull()?.user?.id ?: return@onCommand
 
-            reply(
-                replyMessage,
-                "Manage keyboard:",
-                replyMarkup = buildGranularKeyboard(it.chat.id.toChatId(), userInReply) ?: return@onCommand
-            )
+            if (replyMessage is AccessibleMessage) {
+                reply(
+                    replyMessage,
+                    "Manage keyboard:",
+                    replyMarkup = buildGranularKeyboard(it.chat.id.toChatId(), userInReply) ?: return@onCommand
+                )
+            } else {
+                reply(it) {
+                    regular("Reply to somebody's message to get hist/her rights keyboard")
+                }
+            }
         }
 
         onMessageDataCallbackQuery(
diff --git a/UserChatShared/src/main/kotlin/UserChatShared.kt b/UserChatShared/src/main/kotlin/UserChatShared.kt
index b4c0377..c55102a 100644
--- a/UserChatShared/src/main/kotlin/UserChatShared.kt
+++ b/UserChatShared/src/main/kotlin/UserChatShared.kt
@@ -7,14 +7,11 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPoll
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatShared
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onUserShared
-import dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard
-import dev.inmo.tgbotapi.extensions.utils.types.buttons.requestBotButton
-import dev.inmo.tgbotapi.extensions.utils.types.buttons.requestChatButton
-import dev.inmo.tgbotapi.extensions.utils.types.buttons.requestGroupButton
-import dev.inmo.tgbotapi.extensions.utils.types.buttons.requestUserButton
-import dev.inmo.tgbotapi.extensions.utils.types.buttons.requestUserOrBotButton
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onUsersShared
+import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
 import dev.inmo.tgbotapi.types.BotCommand
 import dev.inmo.tgbotapi.types.chat.PrivateChat
+import dev.inmo.tgbotapi.types.keyboardButtonRequestUserLimit
 import dev.inmo.tgbotapi.types.message.textsources.mention
 import dev.inmo.tgbotapi.types.request.RequestId
 import dev.inmo.tgbotapi.utils.row
@@ -30,52 +27,90 @@ suspend fun main(args: Array<String>) {
     val requestIdUserPremium = RequestId(3)
     val requestIdBot = RequestId(4)
 
-    val requestIdAnyChat = RequestId(5)
-    val requestIdChannel = RequestId(6)
-    val requestIdPublicChannel = RequestId(7)
-    val requestIdPrivateChannel = RequestId(8)
-    val requestIdChannelUserOwner = RequestId(9)
+    val requestIdUsersOrBots = RequestId(5)
+    val requestIdUsersNonPremium = RequestId(6)
+    val requestIdUsersAny = RequestId(7)
+    val requestIdUsersPremium = RequestId(8)
+    val requestIdBots = RequestId(9)
 
-    val requestIdGroup = RequestId(10)
-    val requestIdPublicGroup = RequestId(11)
-    val requestIdPrivateGroup = RequestId(12)
-    val requestIdGroupUserOwner = RequestId(13)
+    val requestIdAnyChat = RequestId(10)
+    val requestIdChannel = RequestId(11)
+    val requestIdPublicChannel = RequestId(12)
+    val requestIdPrivateChannel = RequestId(13)
+    val requestIdChannelUserOwner = RequestId(14)
 
-    val requestIdForum = RequestId(14)
-    val requestIdPublicForum = RequestId(15)
-    val requestIdPrivateForum = RequestId(16)
-    val requestIdForumUserOwner = RequestId(17)
+    val requestIdGroup = RequestId(15)
+    val requestIdPublicGroup = RequestId(16)
+    val requestIdPrivateGroup = RequestId(17)
+    val requestIdGroupUserOwner = RequestId(18)
+
+    val requestIdForum = RequestId(19)
+    val requestIdPublicForum = RequestId(20)
+    val requestIdPrivateForum = RequestId(21)
+    val requestIdForumUserOwner = RequestId(22)
 
     val keyboard = replyKeyboard(
         resizeKeyboard = true,
     ) {
         row {
             requestUserOrBotButton(
-                "\uD83D\uDC64/\uD83E\uDD16",
+                "\uD83D\uDC64/\uD83E\uDD16 (1)",
                 requestIdUserOrBot
             )
         }
         row {
             requestUserButton(
-                "\uD83D\uDC64☆",
+                "\uD83D\uDC64☆ (1)",
                 requestIdUserNonPremium,
                 premiumUser = false
             )
             requestUserButton(
-                "\uD83D\uDC64",
+                "\uD83D\uDC64 (1)",
                 requestIdUserAny,
                 premiumUser = null
             )
             requestUserButton(
-                "\uD83D\uDC64★",
+                "\uD83D\uDC64★ (1)",
                 requestIdUserPremium,
                 premiumUser = true
             )
             requestBotButton(
-                "\uD83E\uDD16",
+                "\uD83E\uDD16 (1)",
                 requestIdBot
             )
         }
+        row {
+            requestUsersOrBotsButton(
+                "\uD83D\uDC64/\uD83E\uDD16",
+                requestIdUsersOrBots,
+                maxCount = keyboardButtonRequestUserLimit.last
+            )
+        }
+        row {
+            requestUsersButton(
+                "\uD83D\uDC64☆",
+                requestIdUsersNonPremium,
+                premiumUser = false,
+                maxCount = keyboardButtonRequestUserLimit.last
+            )
+            requestUsersButton(
+                "\uD83D\uDC64",
+                requestIdUsersAny,
+                premiumUser = null,
+                maxCount = keyboardButtonRequestUserLimit.last
+            )
+            requestUsersButton(
+                "\uD83D\uDC64★",
+                requestIdUsersPremium,
+                premiumUser = true,
+                maxCount = keyboardButtonRequestUserLimit.last
+            )
+            requestBotsButton(
+                "\uD83E\uDD16",
+                requestIdBots,
+                maxCount = keyboardButtonRequestUserLimit.last
+            )
+        }
         row {
             requestChatButton(
                 "\uD83D\uDDE3/\uD83D\uDC65",
@@ -164,25 +199,26 @@ suspend fun main(args: Array<String>) {
             )
         }
 
-        onUserShared {
-            val userId = it.chatEvent.userId
-            val userInfo = runCatchingSafely { getChat(userId) }.getOrNull()
-            reply(
-                it,
-            ) {
-                +"You have shared "
-                +mention(
-                    when (it.chatEvent.requestId) {
-                        requestIdUserOrBot -> "user or bot"
-                        requestIdUserNonPremium -> "non premium user"
-                        requestIdUserAny -> "any user"
-                        requestIdUserPremium -> "premium user"
-                        requestIdBot -> "bot"
-                        else -> "somebody O.o"
-                    },
-                    userId
-                )
-                +" (user info: $userInfo; user id: $userId)"
+        onUsersShared {
+            it.chatEvent.userIds.forEach { userId ->
+                val userInfo = runCatchingSafely { getChat(userId) }.getOrNull()
+                reply(
+                    it,
+                ) {
+                    +"You have shared "
+                    +mention(
+                        when (it.chatEvent.requestId) {
+                            requestIdUserOrBot -> "user or bot"
+                            requestIdUserNonPremium -> "non premium user"
+                            requestIdUserAny -> "any user"
+                            requestIdUserPremium -> "premium user"
+                            requestIdBot -> "bot"
+                            else -> "somebody O.o"
+                        },
+                        userId
+                    )
+                    +" (user info: $userInfo; user id: $userId)"
+                }
             }
         }
 
diff --git a/WebApp/src/jvmMain/kotlin/WebAppServer.kt b/WebApp/src/jvmMain/kotlin/WebAppServer.kt
index 4d61dc9..d3cdf09 100644
--- a/WebApp/src/jvmMain/kotlin/WebAppServer.kt
+++ b/WebApp/src/jvmMain/kotlin/WebAppServer.kt
@@ -1,3 +1,7 @@
+import dev.inmo.kslog.common.KSLog
+import dev.inmo.kslog.common.LogLevel
+import dev.inmo.kslog.common.defaultMessageFormatter
+import dev.inmo.kslog.common.setDefaultKSLog
 import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
 import dev.inmo.micro_utils.ktor.server.createKtorServer
 import dev.inmo.tgbotapi.extensions.api.answers.answer
@@ -14,6 +18,7 @@ import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton
 import dev.inmo.tgbotapi.types.BotCommand
 import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
 import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
+import dev.inmo.tgbotapi.types.LinkPreviewOptions
 import dev.inmo.tgbotapi.types.webAppQueryIdField
 import dev.inmo.tgbotapi.types.webapps.WebAppInfo
 import dev.inmo.tgbotapi.utils.*
@@ -43,6 +48,16 @@ suspend fun main(vararg args: String) {
         args.first(),
         testServer = args.any { it == "testServer" }
     )
+    val isDebug = args.any { it == "debug" }
+
+    if (isDebug) {
+        setDefaultKSLog(
+            KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
+                println(defaultMessageFormatter(level, tag, message, throwable))
+            }
+        )
+    }
+
     val bot = telegramBot(telegramBotAPIUrlsKeeper)
     createKtorServer(
         "0.0.0.0",
@@ -102,8 +117,11 @@ suspend fun main(vararg args: String) {
                     row {
                         webAppButton("Open WebApp", WebAppInfo(args[1]))
                     }
-                }
-
+                },
+                linkPreviewOptions = LinkPreviewOptions.Small(
+                    args[1],
+                    showAboveText = false
+                )
             )
         }
         onCommand("attachment_menu") {
@@ -114,8 +132,11 @@ suspend fun main(vararg args: String) {
                     row {
                         webAppButton("Open WebApp", WebAppInfo(args[1]))
                     }
-                }
-
+                },
+                linkPreviewOptions = LinkPreviewOptions.Large(
+                    args[1],
+                    showAboveText = true
+                )
             )
         }
         onBaseInlineQuery {
diff --git a/build.gradle b/build.gradle
index f0319eb..40b825e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -26,6 +26,6 @@ allprojects {
             }
         }
 
-        maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" }
+        maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
     }
 }
diff --git a/gradle.properties b/gradle.properties
index 9a01b19..7b481be 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,11 +1,11 @@
 kotlin.code.style=official
 org.gradle.parallel=true
 # Due to parallel compilation project require next amount of memory on full build
-org.gradle.jvmargs=-Xmx2g
+org.gradle.jvmargs=-Xmx2344m
 
 
 kotlin_version=1.9.22
-telegram_bot_api_version=9.4.1
-micro_utils_version=0.20.15
+telegram_bot_api_version=10.0.0
+micro_utils_version=0.20.26
 serialization_version=1.6.2
-ktor_version=2.3.6
+ktor_version=2.3.7
diff --git a/settings.gradle b/settings.gradle
index ea37daa..a5231ca 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -41,3 +41,9 @@ include ":LiveLocationsBot"
 include ":StickerSetHandler"
 
 include ":InlineQueriesBot"
+
+include ":ReactionsInfoBot"
+
+include ":LinkPreviewsBot"
+
+include ":BoostsInfoBot"