From e6bdc9b0e58559e443c4523e13b17c3324e12b26 Mon Sep 17 00:00:00 2001 From: Com6235 Date: Tue, 21 May 2024 15:49:02 +0300 Subject: [PATCH] configurator: Release version 1.0 tgbotter: Move project --- .github/workflows/publish.yaml | 5 +- README.md | 160 ++---------------- build.gradle.kts | 131 ++++++-------- configurator/build.gradle.kts | 18 ++ configurator/src/main/kotlin/ConfigLoaders.kt | 61 +++++++ configurator/src/main/kotlin/Loader.kt | 23 +++ configurator/src/main/kotlin/Others.kt | 34 ++++ configurator/src/test/kotlin/ConfigTest.kt | 89 ++++++++++ configurator/src/test/resources/hocon.conf | 10 ++ configurator/src/test/resources/json.json | 13 ++ .../src/test/resources/props.properties | 3 + configurator/src/test/resources/toml.toml | 6 + configurator/src/test/resources/yaml.yaml | 7 + settings.gradle.kts | 6 +- tgbotter/README.md | 138 +++++++++++++++ tgbotter/build.gradle.kts | 70 ++++++++ .../src}/main/kotlin/CommandManager.kt | 4 +- .../src}/main/kotlin/LongPollingBot.kt | 2 +- .../src}/main/kotlin/common/Bot.kt | 0 .../src}/main/kotlin/common/DataClasses.kt | 0 .../src}/main/kotlin/common/Listener.kt | 0 21 files changed, 552 insertions(+), 228 deletions(-) create mode 100644 configurator/build.gradle.kts create mode 100644 configurator/src/main/kotlin/ConfigLoaders.kt create mode 100644 configurator/src/main/kotlin/Loader.kt create mode 100644 configurator/src/main/kotlin/Others.kt create mode 100644 configurator/src/test/kotlin/ConfigTest.kt create mode 100644 configurator/src/test/resources/hocon.conf create mode 100644 configurator/src/test/resources/json.json create mode 100644 configurator/src/test/resources/props.properties create mode 100644 configurator/src/test/resources/toml.toml create mode 100644 configurator/src/test/resources/yaml.yaml create mode 100644 tgbotter/README.md create mode 100644 tgbotter/build.gradle.kts rename {src => tgbotter/src}/main/kotlin/CommandManager.kt (91%) rename {src => tgbotter/src}/main/kotlin/LongPollingBot.kt (98%) rename {src => tgbotter/src}/main/kotlin/common/Bot.kt (100%) rename {src => tgbotter/src}/main/kotlin/common/DataClasses.kt (100%) rename {src => tgbotter/src}/main/kotlin/common/Listener.kt (100%) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 57d54bc..2973c22 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -5,7 +5,7 @@ on: - main jobs: - publish: + publish-and-test: runs-on: ubuntu-latest permissions: contents: write @@ -26,6 +26,9 @@ jobs: - name: Generate and submit dependency graph uses: gradle/actions/dependency-submission@v3 + - name: Test + run: ./gradlew test + - name: Publish package run: ./gradlew publish env: diff --git a/README.md b/README.md index 99a7e51..c56bae7 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ -# Tgbotter +# Maven-Libs -A Kotlin framework for creating telegram bots with ease. Made using [official Telegram Bots Java API](https://github.com/rubenlagus/TelegramBots). +A collection of my libraries for Java/Kotlin. +All packages will be published to [GitHub Packages](https://docs.github.com/ru/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-with-a-personal-access-token), +so you can see all my libs in one place. -Latest version: https://github.com/Com6235/tgBotter/packages/2135012 +## Using my libs -## Installation -### Maven +Since the packages are hosted on GitHub Packages, to download them, +you will need to add my GitHub Packages Maven repository to your repositories: + +### In Maven +To add repositories in Maven, you need to edit your `~\.m2\settings.xml` -Since the packages are hosted on GitHub Packages, to download them, you will need to add my GitHub Packages Maven repository to your `~\.m2\settings.xml` It should look something like this: ```xml github tgbotter repository - https://maven.pkg.github.com/com6235/tgbotter + https://maven.pkg.github.com/com6235/maven-libs @@ -43,28 +47,13 @@ It should look something like this: ``` -Your token MUST be a [classic token](https://github.com/settings/tokens), and it MUST have a `read:packages` permission - -After you added the repository, you can start using my package by adding this to your `pom.xml` -```xml - - io.github.com6235 - tgbotter - ${your desired version} - -``` - -More information on GitHub Packages Maven Registry is [here](https://docs.github.com/ru/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-with-a-personal-access-token) - -### Gradle - -Since the packages are hosted on GitHub Packages, to download them, you will need to add my GitHub Packages Maven repository to your `repositories`: +### In Gradle In `build.gradle.kts`: ```kotlin repositories { maven { - url = uri("https://maven.pkg.github.com/com6235/tgbotter") + url = uri("https://maven.pkg.github.com/com6235/maven-libs") credentials { // this is just example code, you can change it to just strings if you are not going to publish your code username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") // your GitHub username @@ -78,7 +67,7 @@ In `build.gradle`: ```groovy repositories { maven { - url = uri("https://maven.pkg.github.com/com6235/tgbotter") + url = uri("https://maven.pkg.github.com/com6235/maven-libs") credentials { // this is just example code, you can change it to just strings if you are not going to publish your code username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") // your GitHub username @@ -87,123 +76,4 @@ repositories { } } ``` -Your token MUST be a [classic token](https://github.com/settings/tokens), and it MUST have a `read:packages` permission - -After you added the repository, you can start using my package by adding this to `dependencies`: - -In `build.gradle.kts`: -```kotlin -dependencies { - implementation("io.github.com6235:tgbotter:${your desired version}") -} -``` - -In `build.gradle`: -```groovy -dependencies { - implementation 'io.github.com6235:tgbotter:${your desired version}' -} -``` - -## Examples - -### Echo bot - -```kotlin -import io.github.com6235.tgbotter.* -import org.telegram.telegrambots.meta.api.methods.send.SendMessage -import org.telegram.telegrambots.meta.api.objects.message.Message -import org.telegram.telegrambots.meta.generics.TelegramClient - -fun main() { - // Create a LongPollingBot - val bot = LongPollingBot(BotCreationOptions("your token")) - - // Add a listener - bot.addListener(Handler()) - - // Start the bot - bot.start() -} - -// Define a listener -class Handler : Listener { - // Make an event handler - override fun onMessage(message: Message, telegramClient: TelegramClient) { - // Send a message using telegramClient - telegramClient.execute( - SendMessage.builder().text(message.text).chatId(message.chatId).replyToMessageId(message.messageId).build() - ) - } -} -``` - -### Using the command handler - -```kotlin -import io.github.com6235.tgbotter.* -import org.telegram.telegrambots.meta.api.methods.send.SendMessage - -fun main() { - // Create a LongPollingBot - val bot = LongPollingBot(BotCreationOptions("your token")) - - // Add commands - bot.commandManager.addCommand( - Command("start") { handleStart(this) } - ) - bot.commandManager.addCommand( - Command("help") { handleInfo(this) } - ) - - // Start the bot - bot.start() -} - -fun handleStart(commandHandler: CommandHandler) { - commandHandler.telegramClient.execute( - SendMessage.builder() - .chatId(commandHandler.message.chatId) - .text("Hello! Send /help to view the help page.") - .build() - ) -} - -fun handleInfo(commandHandler: CommandHandler) { - commandHandler.telegramClient.execute( - SendMessage.builder() - .chatId(commandHandler.message.chatId) - .text("A very useful help page!") - .build() - ) -} -``` - -## Building from sources - -### Requirements - -- JDK 17 -- [GnuPG](https://www.gnupg.org/) (for signing publications) - -### Building the project - -Use commands -```bash -.\gradlew build -.\gradlew sourcesJar -.\gradlew dokkaJavadocJar -``` -to build all the needed jar-files, or you can do: -```bash -.\gradlew signKotlinPublication -``` -to automatically build and sign everything - -### Publishing to local Maven repository - -Use command -```bash -.\gradlew publishToMavenLocal -``` -to publish all the [artifacts](#building-the-project) to your local Maven repository _(~/.m2/repository)_ \ No newline at end of file +Your token MUST be a [classic token](https://github.com/settings/tokens), and it MUST have `read:packages` scope diff --git a/build.gradle.kts b/build.gradle.kts index 78b070b..c55c3b7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,23 +9,12 @@ plugins { } group = "io.github.com6235" -version = "1.0.3" +version = "root" repositories { mavenCentral() } -dependencies { - testImplementation(kotlin("test")) - - implementation("org.telegram:telegrambots-longpolling:7.2.1") - implementation("org.telegram:telegrambots-webhook:7.2.1") - implementation("org.telegram:telegrambots-client:7.2.1") - api("org.telegram:telegrambots-meta:7.2.1") - - implementation("org.slf4j:slf4j-api:2.0.13") -} - tasks.test { useJUnitPlatform() } @@ -41,84 +30,70 @@ idea { } } -tasks.register("dokkaJavadocJar") { - dependsOn(tasks.dokkaJavadoc) - from(tasks.dokkaJavadoc.flatMap { it.outputDirectory }) - archiveClassifier.set("javadoc") -} +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + apply(plugin = "org.jetbrains.dokka") + apply(plugin = "idea") + apply(plugin = "maven-publish") + apply(plugin = "signing") -tasks.register("sourcesJar") { - from(sourceSets.main.get().allSource) - archiveClassifier.set("sources") -} + repositories { + mavenCentral() + } -configurations { - create("javadoc") - create("sources") -} + tasks.test { + useJUnitPlatform() + } -val jdFile = layout.buildDirectory.file("libs/$name-$version-javadoc.jar") -val jdArtifact = artifacts.add("javadoc", jdFile.get().asFile) { - type = "jar" - builtBy("dokkaJavadocJar") -} + kotlin { + jvmToolchain(17) + } -val srcFile = layout.buildDirectory.file("libs/$name-$version-sources.jar") -val srcArtifact = artifacts.add("sources", srcFile.get().asFile) { - type = "jar" - builtBy("sourcesJar") -} + idea { + module { + isDownloadJavadoc = true + isDownloadSources = true + } + } -publishing { - publications { - create("kotlin") { - from(components["kotlin"]) - artifact(jdArtifact) - artifact(srcArtifact) - pom { - packaging = "jar" - groupId = group.toString() - artifactId = project.name - version = project.version.toString() - name = "${group}:${project.name}" - description = "A framework for creating Telegram bots with ease. Made using official Telegram API" - url = "https://github.com/Com6235/tgBotter" - licenses { - license { - name = "MIT License" - url = "https://opensource.org/license/mit" - } - } - developers { - developer { - id = "com6235" - name = "Com6235" - } - } - scm { - connection = "scm:git:git://github.com/Com6235/tgBotter.git" - developerConnection = "scm:git:ssh://github.com:Com6235/tgBotter.git" - url = "https://github.com/Com6235/tgBotter" + tasks.register("dokkaJavadocJar") { + group = "jar" + dependsOn(tasks.dokkaJavadoc) + from(tasks.dokkaJavadoc.flatMap { it.outputDirectory }) + archiveClassifier.set("javadoc") + } + + tasks.register("sourcesJar") { + group = "jar" + from(sourceSets.main.get().allSource) + archiveClassifier.set("sources") + } + + configurations { + create("javadoc") + create("sources") + } + + publishing { + repositories { + maven { + name = "GitHubPackages" + url = URI("https://maven.pkg.github.com/com6235/maven-libs") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") } } } } - repositories { - maven { - name = "GitHubPackages" - url = URI("https://maven.pkg.github.com/com6235/tgbotter") - credentials { - username = System.getenv("GITHUB_ACTOR") - password = System.getenv("GITHUB_TOKEN") - } + tasks.withType { + onlyIf { + !project.version.toString().endsWith("-SNAPSHOT") } } } -signing { - if (System.getenv("IS_CI") == null) { - useGpgCmd() - sign(publishing.publications["kotlin"]) - } +tasks.jar { + enabled = false } diff --git a/configurator/build.gradle.kts b/configurator/build.gradle.kts new file mode 100644 index 0000000..ea70644 --- /dev/null +++ b/configurator/build.gradle.kts @@ -0,0 +1,18 @@ +group = "io.github.com6235" +version = "1.0" + +plugins { + kotlin("plugin.serialization") version "2.0.0-RC3" +} + +val serializationVersion = "1.6.3" + +dependencies { + testImplementation(kotlin("test")) + + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-hocon:$serializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-properties:$serializationVersion") + implementation("com.charleskorn.kaml:kaml:0.59.0") + implementation("net.peanuuutz.tomlkt:tomlkt:0.3.7") +} \ No newline at end of file diff --git a/configurator/src/main/kotlin/ConfigLoaders.kt b/configurator/src/main/kotlin/ConfigLoaders.kt new file mode 100644 index 0000000..13d42a4 --- /dev/null +++ b/configurator/src/main/kotlin/ConfigLoaders.kt @@ -0,0 +1,61 @@ +package io.github.com6235.configurator + +import com.charleskorn.kaml.Yaml +import com.typesafe.config.ConfigFactory +import com.typesafe.config.ConfigParseOptions +import com.typesafe.config.ConfigSyntax +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.KSerializer +import kotlinx.serialization.hocon.Hocon +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import net.peanuuutz.tomlkt.Toml +import java.io.InputStream +import java.nio.charset.Charset +import java.util.* + +internal class YamlLoader(serializer: KSerializer) : Loader(serializer) { + override fun load(stream: InputStream): T = + yaml.decodeFromString(serializer, stream.readBytes().toString(Charset.defaultCharset())) + + companion object { + val yaml = Yaml() + } +} + +internal class HoconLoader(serializer: KSerializer) : Loader( serializer) { + @OptIn(ExperimentalSerializationApi::class) + override fun load(stream: InputStream): T { + val conf = ConfigFactory.parseString( + stream.readBytes().toString(Charset.defaultCharset()), + ConfigParseOptions.defaults().setSyntax(ConfigSyntax.CONF) + ) + return Hocon.decodeFromConfig(serializer, conf) + } +} + +internal class PropertiesLoader(serializer: KSerializer) : Loader(serializer) { + @OptIn(ExperimentalSerializationApi::class) + override fun load(stream: InputStream): T { + val properties = Properties() + properties.load(stream) + val map: Map = properties.toMap().mapKeys { it.key.toString() }.mapValues { it.value.toString() } + return kotlinx.serialization.properties.Properties.decodeFromMap(serializer, map) + } +} + +internal class JsonLoader(serializer: KSerializer) : Loader(serializer) { + @OptIn(ExperimentalSerializationApi::class) + override fun load(stream: InputStream): T = json.decodeFromStream(serializer, stream) + + companion object { + val json = Json { + prettyPrint = true + } + } +} + +internal class TomlLoader(serializer: KSerializer) : Loader(serializer) { + override fun load(stream: InputStream): T = + Toml.decodeFromString(serializer, stream.readBytes().toString(Charset.defaultCharset())) +} \ No newline at end of file diff --git a/configurator/src/main/kotlin/Loader.kt b/configurator/src/main/kotlin/Loader.kt new file mode 100644 index 0000000..84870f9 --- /dev/null +++ b/configurator/src/main/kotlin/Loader.kt @@ -0,0 +1,23 @@ +package io.github.com6235.configurator + +import kotlinx.serialization.KSerializer +import java.io.* +import java.nio.file.Path +import kotlin.io.path.exists +import kotlin.io.path.extension +import kotlin.io.path.inputStream +import kotlin.io.path.isDirectory + +class ConfigLoader(serializer: KSerializer) { + val fileExtensions = FileExtensions(serializer) + + fun loadConfig(stream: InputStream, fileExtension: String): Config { + val loader = fileExtensions.findExtension(fileExtension) ?: throw NotSerializableException() + return Config(loader.load(stream)) + } + + fun loadConfig(path: Path): Config? { + if (!path.exists() || path.isDirectory()) return null + return loadConfig(path.inputStream(), path.extension) + } +} diff --git a/configurator/src/main/kotlin/Others.kt b/configurator/src/main/kotlin/Others.kt new file mode 100644 index 0000000..d27c148 --- /dev/null +++ b/configurator/src/main/kotlin/Others.kt @@ -0,0 +1,34 @@ +package io.github.com6235.configurator + +import kotlinx.serialization.KSerializer +import java.io.InputStream + +class FileExtensions(serializer: KSerializer) { + @JvmField + val extensions: MutableMap, Loader> = mutableMapOf() + + private val defaults = mapOf( + listOf("json") to JsonLoader(serializer), + listOf("yaml") to YamlLoader(serializer), + listOf("conf", "hocon") to HoconLoader(serializer), + listOf("properties") to PropertiesLoader(serializer), + listOf("toml") to TomlLoader(serializer), + ) + + init { + extensions.putAll(defaults) + } + + fun findExtension(extension: String): Loader? = + extensions.entries.firstOrNull { it.key.contains(extension.lowercase()) }?.value + + fun addExtension(extension: List, loader: Loader) { + extensions[extension.map { it.lowercase() }] = loader + } +} + +data class Config(val data: T) + +abstract class Loader(protected val serializer: KSerializer) { + abstract fun load(stream: InputStream): T +} diff --git a/configurator/src/test/kotlin/ConfigTest.kt b/configurator/src/test/kotlin/ConfigTest.kt new file mode 100644 index 0000000..b9c1dae --- /dev/null +++ b/configurator/src/test/kotlin/ConfigTest.kt @@ -0,0 +1,89 @@ +import io.github.com6235.configurator.ConfigLoader +import kotlinx.serialization.Serializable +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +// HOCON +@Serializable +data class Cocfig(val ktor: KtorCocfig, val aftor: AftorCocfig) +@Serializable +data class KtorCocfig(val biba: Int) +@Serializable +data class AftorCocfig(val befor: BeforAftorCocfig) +@Serializable +data class BeforAftorCocfig(val nwo: NwoBeforAftorCocfig) +@Serializable +data class NwoBeforAftorCocfig(val `uwu-mode`: String) + +// JSON +@Serializable +data class Json(val users: List, val users_count: Int) +@Serializable +data class User(val name: String, val age: Int) + +// PROPERTIES +@Serializable +data class Properties(val potato: String, val `fun`: String) + +// YAML +@Serializable +data class Yaml(val name: String, val jobs: MutableMap) +@Serializable +data class Job(val `runs-on`: String, val steps: MutableMap) +@Serializable +data class Step(val uses: String) + +// TOML +@Serializable +data class Toml(val name: String, val account: Account) +@Serializable +data class Account(val email: String, val password: String, val dateOfBirth: MutableList) + +class ConfigTest { + @Test + fun testLoadingHocon() { + val stream = ConfigTest::class.java.getResourceAsStream("hocon.conf")!! + val s = ConfigLoader(Cocfig.serializer()).loadConfig(stream, "hocon").data + + assertEquals(19, s.ktor.biba) + assertEquals("enadled", s.aftor.befor.nwo.`uwu-mode`) + } + + @Test + fun testLoadingJson() { + val stream = ConfigTest::class.java.getResourceAsStream("json.json")!! + val s = ConfigLoader(Json.serializer()).loadConfig(stream, "json").data + + assertEquals(21, s.users.first { it.name == "Beberich" }.age) + assertEquals(2, s.users_count) + } + + @Test + fun testLoadingProperties() { + val stream = ConfigTest::class.java.getResourceAsStream("props.properties")!! + val s = ConfigLoader(Properties.serializer()).loadConfig(stream, "properties").data + + assertEquals("kartofka", s.potato) + assertEquals("cmex", s.`fun`) + } + + @Test + fun testLoadingYaml() { + val stream = ConfigTest::class.java.getResourceAsStream("yaml.yaml")!! + val s = ConfigLoader(Yaml.serializer()).loadConfig(stream, "yaml").data + + assertEquals("Test", s.name) + assertEquals("my bebera", s.jobs["test"]?.`runs-on`) + } + + @Test + fun testLoadingToml() { + val stream = ConfigTest::class.java.getResourceAsStream("toml.toml")!! + val s = ConfigLoader(Toml.serializer()).loadConfig(stream, "toml").data + + assertEquals("niba", s.name) + assertEquals("01022012", s.account.password) + assertEquals(1, s.account.dateOfBirth[0]) + } + +} diff --git a/configurator/src/test/resources/hocon.conf b/configurator/src/test/resources/hocon.conf new file mode 100644 index 0000000..68a1e8d --- /dev/null +++ b/configurator/src/test/resources/hocon.conf @@ -0,0 +1,10 @@ +ktor { + biba = 19 +} +aftor { + befor { + nwo { + uwu-mode = "enadled" + } + } +} \ No newline at end of file diff --git a/configurator/src/test/resources/json.json b/configurator/src/test/resources/json.json new file mode 100644 index 0000000..ec1b3a0 --- /dev/null +++ b/configurator/src/test/resources/json.json @@ -0,0 +1,13 @@ +{ + "users": [ + { + "name": "Beberich", + "age": 21 + }, + { + "name": "metabrix", + "age": 19 + } + ], + "users_count": 2 +} \ No newline at end of file diff --git a/configurator/src/test/resources/props.properties b/configurator/src/test/resources/props.properties new file mode 100644 index 0000000..9507f22 --- /dev/null +++ b/configurator/src/test/resources/props.properties @@ -0,0 +1,3 @@ +potato=kartofka +fun=cmex +.*asd=asda"asdsax" \ No newline at end of file diff --git a/configurator/src/test/resources/toml.toml b/configurator/src/test/resources/toml.toml new file mode 100644 index 0000000..f6fca20 --- /dev/null +++ b/configurator/src/test/resources/toml.toml @@ -0,0 +1,6 @@ +name = "niba" + +[account] +email = "niba@example.come" +password = "01022012" +dateOfBirth = [1, 2, 2012] \ No newline at end of file diff --git a/configurator/src/test/resources/yaml.yaml b/configurator/src/test/resources/yaml.yaml new file mode 100644 index 0000000..5206aab --- /dev/null +++ b/configurator/src/test/resources/yaml.yaml @@ -0,0 +1,7 @@ +name: Test +jobs: + test: + runs-on: my bebera + steps: + beberich: + uses: aboba \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 8836497..b493f8e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,5 @@ -rootProject.name = "tgbotter" +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" +} +rootProject.name = "maven-libs" +include("tgbotter", "configurator") diff --git a/tgbotter/README.md b/tgbotter/README.md new file mode 100644 index 0000000..354057c --- /dev/null +++ b/tgbotter/README.md @@ -0,0 +1,138 @@ +# Tgbotter + +A Kotlin framework for creating telegram bots with ease. Made using [official Telegram Bots Java API](https://github.com/rubenlagus/TelegramBots). + +Latest version: https://github.com/Com6235/maven-libs/packages/2135012 + +## Using as a dependency +### Maven + +After you added the repository, you can start using my package by adding this to your `pom.xml` +```xml + + io.github.com6235 + tgbotter + ${your desired version} + +``` + +### Gradle + +After you added the repository, you can start using my package by adding this to `dependencies`: + +In `build.gradle.kts`: +```kotlin +dependencies { + implementation("io.github.com6235:tgbotter:${your desired version}") +} +``` + +In `build.gradle`: +```groovy +dependencies { + implementation 'io.github.com6235:tgbotter:${your desired version}' +} +``` + +## Examples + +### Echo bot + +```kotlin +import io.github.com6235.tgbotter.* +import org.telegram.telegrambots.meta.api.methods.send.SendMessage +import org.telegram.telegrambots.meta.api.objects.message.Message +import org.telegram.telegrambots.meta.generics.TelegramClient + +fun main() { + // Create a LongPollingBot + val bot = LongPollingBot(BotCreationOptions("your token")) + + // Add a listener + bot.addListener(Handler()) + + // Start the bot + bot.start() +} + +// Define a listener +class Handler : Listener { + // Make an event handler + override fun onMessage(message: Message, telegramClient: TelegramClient) { + // Send a message using telegramClient + telegramClient.execute( + SendMessage.builder().text(message.text).chatId(message.chatId).replyToMessageId(message.messageId).build() + ) + } +} +``` + +### Using the command handler + +```kotlin +import io.github.com6235.tgbotter.* +import org.telegram.telegrambots.meta.api.methods.send.SendMessage + +fun main() { + // Create a LongPollingBot + val bot = LongPollingBot(BotCreationOptions("your token")) + + // Add commands + bot.commandManager.addCommand( + Command("start") { handleStart(this) } + ) + bot.commandManager.addCommand( + Command("help") { handleInfo(this) } + ) + + // Start the bot + bot.start() +} + +fun handleStart(commandHandler: CommandHandler) { + commandHandler.telegramClient.execute( + SendMessage.builder() + .chatId(commandHandler.message.chatId) + .text("Hello! Send /help to view the help page.") + .build() + ) +} + +fun handleInfo(commandHandler: CommandHandler) { + commandHandler.telegramClient.execute( + SendMessage.builder() + .chatId(commandHandler.message.chatId) + .text("A very useful help page!") + .build() + ) +} +``` + +## Building from sources + +### Requirements + +- JDK 17 +- [GnuPG](https://www.gnupg.org/) (for signing publications) + +### Building the project + +Use commands +```bash +.\gradlew build +.\gradlew sourcesJar +.\gradlew dokkaJavadocJar +``` +to build all the needed jar-files, or you can do: +```bash +.\gradlew signKotlinPublication +``` +to automatically build and sign everything + +### Publishing to local Maven repository + +Use command +```bash +.\gradlew publishToMavenLocal +``` +to publish all the [artifacts](#building-the-project) to your local Maven repository _(~/.m2/repository)_ \ No newline at end of file diff --git a/tgbotter/build.gradle.kts b/tgbotter/build.gradle.kts new file mode 100644 index 0000000..40b52b8 --- /dev/null +++ b/tgbotter/build.gradle.kts @@ -0,0 +1,70 @@ +group = "io.github.com6235" +version = "1.0.4-SNAPSHOT" + +val telegramVersion = "7.2.1" + +dependencies { + testImplementation(kotlin("test")) + + implementation("org.telegram:telegrambots-longpolling:$telegramVersion") + implementation("org.telegram:telegrambots-webhook:$telegramVersion") + implementation("org.telegram:telegrambots-client:$telegramVersion") + api("org.telegram:telegrambots-meta:$telegramVersion") + + implementation("org.slf4j:slf4j-api:2.0.13") +} + +val jdFile = layout.buildDirectory.file("libs/$name-$version-javadoc.jar") +val jdArtifact = artifacts.add("javadoc", jdFile.get().asFile) { + type = "jar" + builtBy("dokkaJavadocJar") +} + +val srcFile = layout.buildDirectory.file("libs/$name-$version-sources.jar") +val srcArtifact = artifacts.add("sources", srcFile.get().asFile) { + type = "jar" + builtBy("sourcesJar") +} + +publishing { + publications { + create("tgbotter") { + from(components["kotlin"]) + artifact(jdArtifact) + artifact(srcArtifact) + pom { + packaging = "jar" + groupId = group.toString() + artifactId = project.name + version = project.version.toString() + name = "${group}:${project.name}" + description = "A framework for creating Telegram bots with ease. Made using official Telegram API" + url = "https://github.com/Com6235/maven-libs" + licenses { + license { + name = "MIT License" + url = "https://opensource.org/license/mit" + } + } + developers { + developer { + id = "com6235" + name = "Com6235" + } + } + scm { + connection = "scm:git:git://github.com/Com6235/maven-libs.git" + developerConnection = "scm:git:ssh://github.com:Com6235/maven-libs.git" + url = "https://github.com/Com6235/maven-libs" + } + } + } + } +} + +signing { + if (System.getenv("IS_CI") == null) { + useGpgCmd() + sign(publishing.publications["tgbotter"]) + } +} diff --git a/src/main/kotlin/CommandManager.kt b/tgbotter/src/main/kotlin/CommandManager.kt similarity index 91% rename from src/main/kotlin/CommandManager.kt rename to tgbotter/src/main/kotlin/CommandManager.kt index 7721ba5..4c0ea55 100644 --- a/src/main/kotlin/CommandManager.kt +++ b/tgbotter/src/main/kotlin/CommandManager.kt @@ -11,7 +11,7 @@ import org.telegram.telegrambots.meta.generics.TelegramClient * Manager for all commands. Runs commands first, before any other event */ class CommandManager(private val bot: Bot) { - internal val handle = Handle(this.bot.telegramClient) + internal val handle = Handle() internal val commandRegex = Regex("[a-z0-9_]+") /** @@ -29,7 +29,7 @@ class CommandManager(private val bot: Bot) { } } - internal class Handle(private val telegramClient: TelegramClient) : Listener { + internal class Handle : Listener { override fun onMessage(message: Message, telegramClient: TelegramClient) { val command = message.text.split(" ") val handler = commands.firstOrNull { "/" + it.name == command[0] } ?: return diff --git a/src/main/kotlin/LongPollingBot.kt b/tgbotter/src/main/kotlin/LongPollingBot.kt similarity index 98% rename from src/main/kotlin/LongPollingBot.kt rename to tgbotter/src/main/kotlin/LongPollingBot.kt index a8c9d85..f3502c2 100644 --- a/src/main/kotlin/LongPollingBot.kt +++ b/tgbotter/src/main/kotlin/LongPollingBot.kt @@ -146,7 +146,7 @@ class LongPollingBot(private val options: BotCreationOptions) : Bot(options) { } private fun afterUpdate(update: Update, type: String, listener: Listener?) { - (listener ?: CommandManager.Handle(bot.telegramClient)).afterUpdate(update, bot.telegramClient) + (listener ?: CommandManager.Handle()).afterUpdate(update, bot.telegramClient) if (!bot.options.logUpdates) return bot.logger.info("${update.updateId} - $type") diff --git a/src/main/kotlin/common/Bot.kt b/tgbotter/src/main/kotlin/common/Bot.kt similarity index 100% rename from src/main/kotlin/common/Bot.kt rename to tgbotter/src/main/kotlin/common/Bot.kt diff --git a/src/main/kotlin/common/DataClasses.kt b/tgbotter/src/main/kotlin/common/DataClasses.kt similarity index 100% rename from src/main/kotlin/common/DataClasses.kt rename to tgbotter/src/main/kotlin/common/DataClasses.kt diff --git a/src/main/kotlin/common/Listener.kt b/tgbotter/src/main/kotlin/common/Listener.kt similarity index 100% rename from src/main/kotlin/common/Listener.kt rename to tgbotter/src/main/kotlin/common/Listener.kt