From d7a7e7153e38d09b7070dbc1cec6d2d742094e68 Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Fri, 21 Apr 2023 23:21:15 +0600
Subject: [PATCH 1/7] add inline queries sample

---
 InlineQueriesBot/README.md                    |  9 +++
 InlineQueriesBot/build.gradle                 | 56 +++++++++++++++
 InlineQueriesBot/src/commonMain/kotlin/Bot.kt | 70 +++++++++++++++++++
 .../src/jvmMain/kotlin/InlineQueriesBot.kt    |  5 ++
 .../src/nativeMain/kotlin/InlineQueriesBot.kt |  7 ++
 gradle.properties                             |  2 +-
 settings.gradle                               |  2 +
 7 files changed, 150 insertions(+), 1 deletion(-)
 create mode 100644 InlineQueriesBot/README.md
 create mode 100644 InlineQueriesBot/build.gradle
 create mode 100644 InlineQueriesBot/src/commonMain/kotlin/Bot.kt
 create mode 100644 InlineQueriesBot/src/jvmMain/kotlin/InlineQueriesBot.kt
 create mode 100644 InlineQueriesBot/src/nativeMain/kotlin/InlineQueriesBot.kt

diff --git a/InlineQueriesBot/README.md b/InlineQueriesBot/README.md
new file mode 100644
index 0000000..4765c04
--- /dev/null
+++ b/InlineQueriesBot/README.md
@@ -0,0 +1,9 @@
+# RandomFileSenderBot
+
+This bot will send random file from input folder OR from bot working folder
+
+## Launch
+
+```bash
+../gradlew run --args="BOT_TOKEN[ optional/folder/path]"
+```
diff --git a/InlineQueriesBot/build.gradle b/InlineQueriesBot/build.gradle
new file mode 100644
index 0000000..a574fb8
--- /dev/null
+++ b/InlineQueriesBot/build.gradle
@@ -0,0 +1,56 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+plugins {
+    id "org.jetbrains.kotlin.multiplatform"
+}
+
+apply plugin: 'application'
+
+mainClassName="InlineQueriesBotKt"
+
+
+kotlin {
+    def hostOs = System.getProperty("os.name")
+    def isMingwX64 = hostOs.startsWith("Windows")
+    def nativeTarget
+    if (hostOs == "Linux") nativeTarget = linuxX64("native") { binaries { executable() } }
+    else if (isMingwX64) nativeTarget = mingwX64("native") { binaries { executable() } }
+    else throw new GradleException("Host OS is not supported in Kotlin/Native.")
+
+    jvm()
+
+    sourceSets {
+        commonMain {
+            dependencies {
+                implementation kotlin('stdlib')
+
+                api "dev.inmo:tgbotapi:$telegram_bot_api_version"
+            }
+        }
+
+        nativeMain {
+            dependencies {
+                def engine
+
+                if (hostOs == "Linux") engine = "curl"
+                else if (isMingwX64) engine = "winhttp"
+                else throw new GradleException("Host OS is not supported in Kotlin/Native.")
+
+                api "io.ktor:ktor-client-$engine:$ktor_version"
+            }
+        }
+    }
+}
+
+dependencies {
+    implementation 'io.ktor:ktor-client-logging-jvm:2.3.0'
+}
+
diff --git a/InlineQueriesBot/src/commonMain/kotlin/Bot.kt b/InlineQueriesBot/src/commonMain/kotlin/Bot.kt
new file mode 100644
index 0000000..64cbcb5
--- /dev/null
+++ b/InlineQueriesBot/src/commonMain/kotlin/Bot.kt
@@ -0,0 +1,70 @@
+import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
+import dev.inmo.tgbotapi.extensions.api.answers.answer
+import dev.inmo.tgbotapi.extensions.api.bot.getMe
+import dev.inmo.tgbotapi.extensions.api.send.reply
+import dev.inmo.tgbotapi.extensions.api.telegramBot
+import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onBaseInlineQuery
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onDeepLink
+import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton
+import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
+import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
+import dev.inmo.tgbotapi.types.inlineQueryAnswerResultsLimit
+import dev.inmo.tgbotapi.utils.buildEntities
+
+/**
+ * This bot will send files inside of working directory OR from directory in the second argument.
+ * You may send /send_file command to this bot to get random file from the directory OR
+ * `/send_file $number` when you want to receive required number of files. For example,
+ * /send_file and `/send_file 1` will have the same effect - bot will send one random file.
+ * But if you will send `/send_file 5` it will choose 5 random files and send them as group
+ */
+suspend fun doInlineQueriesBot(token: String) {
+    val bot = telegramBot(token)
+
+    bot.buildBehaviourWithLongPolling(
+        defaultExceptionsHandler = { it.printStackTrace() },
+    ) {
+        onBaseInlineQuery {
+            val page = it.offset.toIntOrNull() ?: 0
+            val results = (0 until inlineQueryAnswerResultsLimit.last).map {
+                (page * inlineQueryAnswerResultsLimit.last) + it
+            }
+
+            answer(
+                it,
+                results = results.map { resultNumber ->
+                    val resultAsString = resultNumber.toString()
+                    InlineQueryResultArticle(
+                        resultAsString,
+                        "Title $resultNumber",
+                        InputTextMessageContent(
+                            buildEntities {
+                                +"Result text of " + resultNumber.toString() + " result:\n"
+                                +it.query
+                            }
+                        ),
+                        description = "Description of $resultNumber result"
+                    )
+                },
+                cachedTime = 0,
+                isPersonal = true,
+                button = InlineQueryResultsButton.Start(
+                    "Text of button with page $page",
+                    "deep_link_for_page_$page"
+                ),
+                nextOffset = (page + 1).toString()
+            )
+        }
+
+        onDeepLink { (message, deepLink) ->
+            reply(message, deepLink)
+        }
+
+        allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
+            println(it)
+        }
+
+        println(getMe())
+    }.join()
+}
diff --git a/InlineQueriesBot/src/jvmMain/kotlin/InlineQueriesBot.kt b/InlineQueriesBot/src/jvmMain/kotlin/InlineQueriesBot.kt
new file mode 100644
index 0000000..2d20c79
--- /dev/null
+++ b/InlineQueriesBot/src/jvmMain/kotlin/InlineQueriesBot.kt
@@ -0,0 +1,5 @@
+import dev.inmo.micro_utils.common.MPPFile
+
+suspend fun main(args: Array<String>) {
+    doInlineQueriesBot(args.first())
+}
diff --git a/InlineQueriesBot/src/nativeMain/kotlin/InlineQueriesBot.kt b/InlineQueriesBot/src/nativeMain/kotlin/InlineQueriesBot.kt
new file mode 100644
index 0000000..8daeb70
--- /dev/null
+++ b/InlineQueriesBot/src/nativeMain/kotlin/InlineQueriesBot.kt
@@ -0,0 +1,7 @@
+import kotlinx.coroutines.runBlocking
+
+fun main(args: Array<String>) {
+    runBlocking {
+        doInlineQueriesBot(args.first())
+    }
+}
diff --git a/gradle.properties b/gradle.properties
index 823884b..b2a959c 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx2g
 
 
 kotlin_version=1.8.20
-telegram_bot_api_version=7.0.2
+telegram_bot_api_version=7.1.0-branch_7.1.0-build1602
 micro_utils_version=0.17.8
 serialization_version=1.5.0
 ktor_version=2.3.0
diff --git a/settings.gradle b/settings.gradle
index a665bb3..a76f386 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -37,3 +37,5 @@ include ":RightsChangerBot"
 include ":LiveLocationsBot"
 
 include ":StickerSetHandler"
+
+include ":InlineQueriesBot"

From 24c74f3b1ad3929a3536bdf4afce037ceb88269e Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 22 Apr 2023 00:11:56 +0600
Subject: [PATCH 2/7] in keyboards bot add sample with sending of inline query

---
 .../src/commonMain/kotlin/KeyboardsBot.kt     | 58 +++++++++++++++++--
 WebApp/src/jvmMain/kotlin/WebAppServer.kt     | 17 ++++++
 2 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt b/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt
index 3f69b47..b808b8e 100644
--- a/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt
+++ b/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt
@@ -4,12 +4,17 @@ import dev.inmo.tgbotapi.bot.ktor.telegramBot
 import dev.inmo.tgbotapi.extensions.api.answers.answer
 import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
 import dev.inmo.tgbotapi.extensions.api.edit.edit
+import dev.inmo.tgbotapi.extensions.api.edit.editMessageText
+import dev.inmo.tgbotapi.extensions.api.edit.reply_markup.editMessageReplyMarkup
+import dev.inmo.tgbotapi.extensions.api.edit.text.editMessageText
 import dev.inmo.tgbotapi.extensions.api.send.*
 import dev.inmo.tgbotapi.extensions.behaviour_builder.*
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
 import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
 import dev.inmo.tgbotapi.extensions.utils.withContent
 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.message.content.TextContent
 import dev.inmo.tgbotapi.utils.*
 import kotlinx.coroutines.*
@@ -55,6 +60,16 @@ fun InlineKeyboardBuilder.includePageButtons(page: Int, count: Int) {
             dataButton(">>", "$count $count")
         }
     }
+    row {
+        inlineQueryInChosenChatButton(
+            "Send somebody page",
+            query = "$page $count",
+            allowUsers = true,
+            allowBots = true,
+            allowGroups = true,
+            allowChannels = true,
+        )
+    }
 }
 
 suspend fun activateKeyboardsBot(
@@ -71,9 +86,7 @@ suspend fun activateKeyboardsBot(
             reply(
                 message,
                 replyMarkup = inlineKeyboard {
-                    row {
-                        includePageButtons(1, numberOfPages)
-                    }
+                    includePageButtons(1, numberOfPages)
                 }
             ) {
                 regular("Your inline keyboard with $numberOfPages pages")
@@ -92,15 +105,48 @@ suspend fun activateKeyboardsBot(
                     return@onMessageDataCallbackQuery
                 },
                 replyMarkup = inlineKeyboard {
-                    row {
-                        includePageButtons(page, count)
-                    }
+                    includePageButtons(page, count)
                 }
             ) {
                 regular("This is $page of $count")
             }
             answer(it)
         }
+        onInlineMessageIdDataCallbackQuery {
+            val (page, count) = it.data.parsePageAndCount() ?: it.let {
+                answer(it, "Unsupported data :(")
+                return@onInlineMessageIdDataCallbackQuery
+            }
+
+            editMessageText(
+                it.inlineMessageId,
+                replyMarkup = inlineKeyboard {
+                    includePageButtons(page, count)
+                }
+            ) {
+                regular("This is $page of $count")
+            }
+            answer(it)
+        }
+
+        onBaseInlineQuery {
+            val page = it.query.takeWhile { it.isDigit() }.toIntOrNull() ?: return@onBaseInlineQuery
+            val count = it.query.removePrefix(page.toString()).dropWhile { !it.isDigit() }.takeWhile { it.isDigit() }.toIntOrNull() ?: return@onBaseInlineQuery
+
+            answer(
+                it,
+                results = listOf(
+                    InlineQueryResultArticle(
+                        it.query,
+                        "Send buttons",
+                        InputTextMessageContent("It is sent via inline mode inline buttons"),
+                        replyMarkup = inlineKeyboard {
+                            includePageButtons(page, count)
+                        }
+                    )
+                )
+            )
+        }
 
         onUnhandledCommand {
             reply(
diff --git a/WebApp/src/jvmMain/kotlin/WebAppServer.kt b/WebApp/src/jvmMain/kotlin/WebAppServer.kt
index 0b800bf..9423482 100644
--- a/WebApp/src/jvmMain/kotlin/WebAppServer.kt
+++ b/WebApp/src/jvmMain/kotlin/WebAppServer.kt
@@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.extensions.api.send.*
 import dev.inmo.tgbotapi.extensions.api.telegramBot
 import dev.inmo.tgbotapi.extensions.behaviour_builder.*
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
+import dev.inmo.tgbotapi.extensions.utils.formatting.makeTelegramStartattach
 import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
 import dev.inmo.tgbotapi.types.BotCommand
 import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
@@ -73,6 +74,7 @@ suspend fun main(vararg args: String) {
     bot.buildBehaviourWithLongPolling(
         defaultExceptionsHandler = { it.printStackTrace() }
     ) {
+        val me = getMe()
         onCommand("reply_markup") {
             reply(
                 it,
@@ -97,6 +99,18 @@ suspend fun main(vararg args: String) {
 
             )
         }
+        onCommand("attachment_menu") {
+            reply(
+                it,
+                ,
+                replyMarkup = inlineKeyboard {
+                    row {
+                        webAppButton("Open WebApp", WebAppInfo(args[1]))
+                    }
+                }
+
+            )
+        }
         onUnhandledCommand {
             reply(
                 it,
@@ -106,6 +120,9 @@ suspend fun main(vararg args: String) {
                 }
             )
         }
+        onWriteAccessAllowed(initialFilter = { it.chatEvent.webAppName != null }) {
+            send(it.chat, "Thanks for adding ${it.chatEvent.webAppName} to the attachment menu")
+        }
         setMyCommands(
             BotCommand("reply_markup", "Use to get reply markup keyboard with web app trigger"),
             BotCommand("inline", "Use to get inline keyboard with web app trigger"),

From eccbe71e6878cc8b98367f3b685fc372471d62d9 Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 22 Apr 2023 00:17:39 +0600
Subject: [PATCH 3/7] finish checking update

---
 GetMeBot/src/main/kotlin/GetMeBot.kt | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/GetMeBot/src/main/kotlin/GetMeBot.kt b/GetMeBot/src/main/kotlin/GetMeBot.kt
index 78c18f5..aa883dd 100644
--- a/GetMeBot/src/main/kotlin/GetMeBot.kt
+++ b/GetMeBot/src/main/kotlin/GetMeBot.kt
@@ -1,16 +1,5 @@
 import dev.inmo.tgbotapi.bot.ktor.telegramBot
 import dev.inmo.tgbotapi.extensions.api.bot.getMe
-import dev.inmo.tgbotapi.extensions.api.chat.forum.closeForumTopic
-import dev.inmo.tgbotapi.extensions.api.chat.forum.createForumTopic
-import dev.inmo.tgbotapi.extensions.api.chat.forum.deleteForumTopic
-import dev.inmo.tgbotapi.extensions.api.chat.forum.reopenForumTopic
-import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour
-import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
-import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onForumTopicClosed
-import dev.inmo.tgbotapi.types.ChatId
-import dev.inmo.tgbotapi.types.CustomEmojiId
-import dev.inmo.tgbotapi.types.ForumTopic
-import kotlinx.coroutines.delay
 
 /**
  * This is one of the most easiest bot - it will just print information about itself

From 3e2ccf9cf167fc34440add8f777aea8110ef6b2d Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 22 Apr 2023 11:06:03 +0600
Subject: [PATCH 4/7] add answerInlineQuery with WebAppInfo

---
 WebApp/src/jvmMain/kotlin/WebAppServer.kt | 13 ++++++++++++-
 gradle.properties                         |  2 +-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/WebApp/src/jvmMain/kotlin/WebAppServer.kt b/WebApp/src/jvmMain/kotlin/WebAppServer.kt
index 9423482..5970521 100644
--- a/WebApp/src/jvmMain/kotlin/WebAppServer.kt
+++ b/WebApp/src/jvmMain/kotlin/WebAppServer.kt
@@ -1,6 +1,7 @@
 import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
 import dev.inmo.micro_utils.ktor.server.createKtorServer
 import dev.inmo.tgbotapi.extensions.api.answers.answer
+import dev.inmo.tgbotapi.extensions.api.answers.answerInlineQuery
 import dev.inmo.tgbotapi.extensions.api.bot.getMe
 import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
 import dev.inmo.tgbotapi.extensions.api.send.*
@@ -9,6 +10,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.*
 import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
 import dev.inmo.tgbotapi.extensions.utils.formatting.makeTelegramStartattach
 import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
+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
@@ -102,7 +104,7 @@ suspend fun main(vararg args: String) {
         onCommand("attachment_menu") {
             reply(
                 it,
-                ,
+                "Button",
                 replyMarkup = inlineKeyboard {
                     row {
                         webAppButton("Open WebApp", WebAppInfo(args[1]))
@@ -111,6 +113,15 @@ suspend fun main(vararg args: String) {
 
             )
         }
+        onBaseInlineQuery {
+            answerInlineQuery(
+                it,
+                button = InlineQueryResultsButton.invoke(
+                    "Open webApp",
+                    WebAppInfo(args[1])
+                )
+            )
+        }
         onUnhandledCommand {
             reply(
                 it,
diff --git a/gradle.properties b/gradle.properties
index b2a959c..57e16cf 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx2g
 
 
 kotlin_version=1.8.20
-telegram_bot_api_version=7.1.0-branch_7.1.0-build1602
+telegram_bot_api_version=7.1.0-branch_7.1.0-build1610
 micro_utils_version=0.17.8
 serialization_version=1.5.0
 ktor_version=2.3.0

From 8d33dc0ab2d8578ed843640943d064ea2022b8bf Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 22 Apr 2023 16:36:14 +0600
Subject: [PATCH 5/7] Update README.md

---
 InlineQueriesBot/README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/InlineQueriesBot/README.md b/InlineQueriesBot/README.md
index 4765c04..7661fdb 100644
--- a/InlineQueriesBot/README.md
+++ b/InlineQueriesBot/README.md
@@ -1,9 +1,9 @@
-# RandomFileSenderBot
+# InlineQueriesBot
 
-This bot will send random file from input folder OR from bot working folder
+This bot will form the inline queries for you. For that feature you should explicitly enable inline queries in bot settings
 
 ## Launch
 
 ```bash
-../gradlew run --args="BOT_TOKEN[ optional/folder/path]"
+../gradlew run --args="BOT_TOKEN"
 ```

From 6719b9e17cd17547a658241d4b5edb302586365d Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 22 Apr 2023 16:39:59 +0600
Subject: [PATCH 6/7] Update Bot.kt

---
 InlineQueriesBot/src/commonMain/kotlin/Bot.kt | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/InlineQueriesBot/src/commonMain/kotlin/Bot.kt b/InlineQueriesBot/src/commonMain/kotlin/Bot.kt
index 64cbcb5..03027c0 100644
--- a/InlineQueriesBot/src/commonMain/kotlin/Bot.kt
+++ b/InlineQueriesBot/src/commonMain/kotlin/Bot.kt
@@ -13,11 +13,8 @@ import dev.inmo.tgbotapi.types.inlineQueryAnswerResultsLimit
 import dev.inmo.tgbotapi.utils.buildEntities
 
 /**
- * This bot will send files inside of working directory OR from directory in the second argument.
- * You may send /send_file command to this bot to get random file from the directory OR
- * `/send_file $number` when you want to receive required number of files. For example,
- * /send_file and `/send_file 1` will have the same effect - bot will send one random file.
- * But if you will send `/send_file 5` it will choose 5 random files and send them as group
+ * Thi bot will create inline query answers. You
+ * should enable inline queries in bot settings
  */
 suspend fun doInlineQueriesBot(token: String) {
     val bot = telegramBot(token)

From 0cfe60fd77c3cff07b025f6d768277fdd6f538d4 Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 22 Apr 2023 20:31:41 +0600
Subject: [PATCH 7/7] Update gradle.properties

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 57e16cf..5227a4d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx2g
 
 
 kotlin_version=1.8.20
-telegram_bot_api_version=7.1.0-branch_7.1.0-build1610
+telegram_bot_api_version=7.1.0
 micro_utils_version=0.17.8
 serialization_version=1.5.0
 ktor_version=2.3.0