diff --git a/KeyboardsBot/KeyboardsBotLib/build.gradle b/KeyboardsBot/KeyboardsBotLib/build.gradle new file mode 100644 index 0000000..50db973 --- /dev/null +++ b/KeyboardsBot/KeyboardsBotLib/build.gradle @@ -0,0 +1,32 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +plugins { + id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version" +} + + +kotlin { + jvm() + js(IR) { + browser() + binaries.executable() + } + + sourceSets { + commonMain { + dependencies { + implementation kotlin('stdlib') + + api "dev.inmo:tgbotapi:$telegram_bot_api_version" + } + } + } +} diff --git a/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt b/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt new file mode 100644 index 0000000..448e607 --- /dev/null +++ b/KeyboardsBot/KeyboardsBotLib/src/commonMain/kotlin/KeyboardsBot.kt @@ -0,0 +1,107 @@ +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions +import dev.inmo.tgbotapi.extensions.api.bot.getMe +import dev.inmo.tgbotapi.bot.Ktor.telegramBot +import dev.inmo.tgbotapi.extensions.api.answers.answer +import dev.inmo.tgbotapi.extensions.api.edit.text.editMessageText +import dev.inmo.tgbotapi.extensions.api.send.* +import dev.inmo.tgbotapi.extensions.api.send.media.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups +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.types.buttons.* +import dev.inmo.tgbotapi.extensions.utils.withContent +import dev.inmo.tgbotapi.types.message.content.TextContent +import kotlinx.coroutines.* + +private const val nextPageData = "next" +private const val previousPageData = "previous" + +fun String.parsePageAndCount(): Pair? { + val (pageString, countString) = split(" ").takeIf { it.count() > 1 } ?: return null + return Pair( + pageString.toIntOrNull() ?: return null, + countString.toIntOrNull() ?: return null + ) +} + +fun InlineKeyboardBuilder.includePageButtons(page: Int, count: Int) { + val numericButtons = listOfNotNull( + page - 1, + page, + page + 1, + ) + row { + val numbersRange = 1 .. count + numericButtons.forEach { + if (it in numbersRange) { + dataButton(it.toString(), "$it $count") + } + } + } + + row { + if (page - 1 > 2) { + dataButton("<<", "1 $count") + } + if (page - 1 > 1) { + dataButton("<", "${page - 2} $count") + } + + if (page + 1 < count) { + dataButton(">", "${page + 2} $count") + } + if (page + 2 < count) { + dataButton(">>", "$count $count") + } + } +} + +suspend fun activateKeyboardsBot( + token: String, + print: (Any) -> Unit +) { + val bot = telegramBot(token) + + print(bot.getMe()) + + bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) { + onCommandWithArgs("inline") { message, args -> + val numberOfPages = args.firstOrNull() ?.toIntOrNull() ?: 10 + reply( + message, + "Your inline keyboard with $numberOfPages pages", + replyMarkup = inlineKeyboard { + row { + includePageButtons(1, numberOfPages) + } + } + ) + } + + onMessageDataCallbackQuery { + val (page, count) = it.data.parsePageAndCount() ?: it.let { + answer(it, "Unsupported data :(") + return@onMessageDataCallbackQuery + } + + editMessageText( + it.message.withContent() ?: it.let { + answer(it, "Unsupported message type :(") + return@onMessageDataCallbackQuery + }, + "This is $page of $count", + replyMarkup = inlineKeyboard { + row { + includePageButtons(page, count) + } + } + ) + } + + allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { + println(it) + } + }.join() +} diff --git a/KeyboardsBot/KeyboardsBotLib/src/jsMain/kotlin/KeyboardsBot.kt b/KeyboardsBot/KeyboardsBotLib/src/jsMain/kotlin/KeyboardsBot.kt new file mode 100644 index 0000000..3e31148 --- /dev/null +++ b/KeyboardsBot/KeyboardsBotLib/src/jsMain/kotlin/KeyboardsBot.kt @@ -0,0 +1,32 @@ +import kotlinx.browser.document +import kotlinx.coroutines.* +import org.w3c.dom.* + +private val scope = CoroutineScope(Dispatchers.Default) + +fun main() { + document.addEventListener( + "DOMContentLoaded", + { + val botsContainer = document.getElementById("bots_container") ?: return@addEventListener + + (document.getElementById("bot_token_form") as? HTMLFormElement) ?.onsubmit = { + (document.getElementById("bot_token") as? HTMLInputElement) ?.value ?.let { token -> + val botContainer = document.createElement("div") as HTMLDivElement + botsContainer.append(botContainer) + + val infoDiv = document.createElement("div") as HTMLDivElement + botContainer.append(infoDiv) + + scope.launch { + activateKeyboardsBot(token) { + infoDiv.innerHTML = it.toString() + } + } + } + + false + } + } + ) +} diff --git a/KeyboardsBot/KeyboardsBotLib/src/jsMain/resources/index.html b/KeyboardsBot/KeyboardsBotLib/src/jsMain/resources/index.html new file mode 100644 index 0000000..69281d3 --- /dev/null +++ b/KeyboardsBot/KeyboardsBotLib/src/jsMain/resources/index.html @@ -0,0 +1,16 @@ + + + + + Keyboards bot + + +
+ + +
+
Type your bot token to the input above to start its work
+ +
+ + diff --git a/KeyboardsBot/jvm_launcher/build.gradle b/KeyboardsBot/jvm_launcher/build.gradle new file mode 100644 index 0000000..47b4729 --- /dev/null +++ b/KeyboardsBot/jvm_launcher/build.gradle @@ -0,0 +1,21 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName="KeyboardsBotJvmKt" + + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + implementation project(":KeyboardsBot:KeyboardsBotLib") +} diff --git a/KeyboardsBot/jvm_launcher/src/main/kotlin/KeyboardsBotJvm.kt b/KeyboardsBot/jvm_launcher/src/main/kotlin/KeyboardsBotJvm.kt new file mode 100644 index 0000000..9ef93b6 --- /dev/null +++ b/KeyboardsBot/jvm_launcher/src/main/kotlin/KeyboardsBotJvm.kt @@ -0,0 +1,10 @@ +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +suspend fun main(args: Array) { + withContext(Dispatchers.IO) { // IO for inheriting of it in side of activateKeyboardsBot + activateKeyboardsBot(args.first()) { + println(it) + } + } +} diff --git a/gradle.properties b/gradle.properties index fe50aec..0903981 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,5 +3,5 @@ org.gradle.parallel=true kotlin_version=1.6.10 -telegram_bot_api_version=0.38.11 -micro_utils_version=0.9.17 +telegram_bot_api_version=0.38.12 +micro_utils_version=0.9.19 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cde1e36..0dfb4f8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip diff --git a/settings.gradle b/settings.gradle index fb925d4..e66b75d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,9 +1,19 @@ include ":ForwardInfoSenderBot" + include ":RandomFileSenderBot" + include ":HelloBot" + include ":GetMeBot" + include ":FilesLoaderBot" + include ":ResenderBot:ResenderBotLib" include ":ResenderBot:jvm_launcher" + +include ":KeyboardsBot:KeyboardsBotLib" +include ":KeyboardsBot:jvm_launcher" + include ":SlotMachineDetectorBot" + include ":FSMBot"