diff --git a/WebApp/src/jvmMain/kotlin/WebAppServer.kt b/WebApp/src/jvmMain/kotlin/WebAppServer.kt index b50a3c9..f067cd2 100644 --- a/WebApp/src/jvmMain/kotlin/WebAppServer.kt +++ b/WebApp/src/jvmMain/kotlin/WebAppServer.kt @@ -63,10 +63,7 @@ suspend fun main(vararg args: String) { val bot = telegramBot(telegramBotAPIUrlsKeeper) createKtorServer( "0.0.0.0", - args.getOrNull(2) ?.toIntOrNull() ?: 8080, - additionalEngineEnvironmentConfigurator = { - parentCoroutineContext += Dispatchers.IO - } + args.getOrNull(2) ?.toIntOrNull() ?: 8080 ) { routing { val baseJsFolder = File("WebApp/build/dist/js/") diff --git a/WebHooks/README.md b/WebHooks/README.md new file mode 100644 index 0000000..34be518 --- /dev/null +++ b/WebHooks/README.md @@ -0,0 +1,28 @@ +# WebHooks + +Launches webhook-based simple bot. Use `/start` with bot to get simple info about webhooks + +## Launch + +```bash +../gradlew run --args="BOT_TOKEN https://sample.com it/is/subpath 8080 debug" +``` + +Required arguments: + +1. Token +2. Arguments starting with `https://` + +Optional arguments: + +* Any argument == `debug` to enable debug mode +* Any argument **not** starting with `https://` and **not** equal to `debug` as **subpath** (will be used as +subroute to place listening of webhooks) +* Any argument as number of port + +Sample: `TOKEN https://sample.com it/is/subpath 8080` will result to: + +* `TOKEN` used as token +* Bot will set up its webhook info as `https://sample.com/it/is/subpath` +* Bot will set up to listen webhooks on route `it/is/subpath` +* Bot will start to listen any incoming request on port `8080` and url `0.0.0.0` diff --git a/WebHooks/build.gradle b/WebHooks/build.gradle new file mode 100644 index 0000000..c6e3b5c --- /dev/null +++ b/WebHooks/build.gradle @@ -0,0 +1,23 @@ +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName="WebHooksKt" + + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + implementation "dev.inmo:tgbotapi:$telegram_bot_api_version" + implementation "dev.inmo:micro_utils.ktor.server:$micro_utils_version" + implementation "io.ktor:ktor-server-cio:$ktor_version" +} diff --git a/WebHooks/src/main/kotlin/WebHooks.kt b/WebHooks/src/main/kotlin/WebHooks.kt new file mode 100644 index 0000000..3c0bbbe --- /dev/null +++ b/WebHooks/src/main/kotlin/WebHooks.kt @@ -0,0 +1,87 @@ +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.ktor.server.createKtorServer +import dev.inmo.tgbotapi.bot.ktor.telegramBot +import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.api.webhook.setWebhookInfo +import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour +import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand +import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.includeWebhookHandlingInRoute +import dev.inmo.tgbotapi.types.BotCommand +import dev.inmo.tgbotapi.types.chat.PrivateChat +import dev.inmo.tgbotapi.utils.buildEntities +import io.ktor.server.routing.* + +/** + * Launches webhook-based simple bot. Required arguments: + * + * 1. Token + * *. Arguments starting with `https://` + * + * Optional arguments: + * + * *. Any argument == `debug` to enable debug mode + * *. Any argument **not** starting with `https://` and **not** equal to `debug` as **subpath** (will be used as + * subroute to place listening of webhooks) + * *. Any argument as number of port + * + * Sample: `TOKEN https://sample.com it/is/subpath 8080` will result to: + * + * * `TOKEN` used as token + * * Bot will set up its webhook info as `https://sample.com/it/is/subpath` + * * Bot will set up to listen webhooks on route `it/is/subpath` + * * Bot will start to listen any incoming request on port `8080` and url `0.0.0.0` + */ +suspend fun main(args: Array) { + val botToken = args.first() + val address = args.first { it.startsWith("https://") } + val subpath = args.drop(1).firstOrNull { it != address && it != "debug" } + val port = args.firstNotNullOfOrNull { it.toIntOrNull() } ?: 8080 + 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(botToken) + + val behaviourContext = bot.buildBehaviour (defaultExceptionsHandler = { it.printStackTrace() }) { + onCommand("start", initialFilter = { it.chat is PrivateChat }) { + reply( + it, + buildEntities { + +"Url: $address" + "\n" + +"Listening server: 0.0.0.0" + "\n" + +"Listening port: $port" + } + ) + } + + setMyCommands(BotCommand("start", "Get webhook info")) + } + + val webhookInfoSubpath = subpath ?.let { "/" + it.removePrefix("/") } ?: "" // drop leading `/` to add it in the beginning for correct construction of subpath + bot.setWebhookInfo(address + webhookInfoSubpath) + + createKtorServer( + "0.0.0.0", + port, + ) { + routing { + if (subpath == null) { + includeWebhookHandlingInRoute(behaviourContext, block = behaviourContext.asUpdateReceiver) + } else { + route(subpath) { + includeWebhookHandlingInRoute(behaviourContext, block = behaviourContext.asUpdateReceiver) + } + } + } + }.start(true) +} diff --git a/gradle.properties b/gradle.properties index afcf2fb..d0319f0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ kotlin.daemon.jvmargs=-Xmx3g -Xms500m kotlin_version=2.0.21 -telegram_bot_api_version=18.2.2 -micro_utils_version=0.22.7 +telegram_bot_api_version=19.0.0 +micro_utils_version=0.23.0 serialization_version=1.7.3 -ktor_version=2.3.12 +ktor_version=3.0.1 diff --git a/settings.gradle b/settings.gradle index 69b62eb..bfdabe8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -57,3 +57,5 @@ include ":GiveawaysBot" include ":CustomBot" include ":MemberUpdatedWatcherBot" + +include ":WebHooks"