Skip to content

Commit

Permalink
7.6.2 (#303)
Browse files Browse the repository at this point in the history
* Move all sealed structure serialization to unified approach.
  • Loading branch information
vendelieu authored Dec 16, 2024
1 parent 69b8d9a commit ebba15d
Show file tree
Hide file tree
Showing 51 changed files with 348 additions and 179 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Telegram-bot (KtGram) Changelog

### 7.6.2

* Move all sealed structure serialization to unified approach.

### 7.6.1

* Fixed `ChatMemberUpdated` serde issue.
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ from [packages](https://github.com/vendelieu?tab=packages&repo_name=telegram-bot
with Ktor.
- [Spring Boot usage](https://github.com/vendelieu/telegram-bot_template/tree/spring-bot) - An example of using the bot
organically in the Spring ecosystem, using its built-in DI.
- [Heroku ready example](https://github.com/vendelieu/telegram-bot_template/tree/heroku) - An example of a bot working
via Heroku.
- [GatekeeperBot](https://github.com/ktgram/gatekeeper) - Gatekeeper bot.
- [Native example](https://github.com/ktgram/native-example) - An example of using a bot with Kotlin Native target.
- [Web app](https://github.com/ktgram/webapp) - Example of a bot using Telegram Webapps.

Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/ConfiguredKotlinExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
private val jvmTargetVer = JvmTarget.JVM_17
private val optIns: Array<String> = arrayOf(
"-opt-in=eu.vendeli.tgbot.annotations.internal.KtGramInternal",
"-opt-in=eu.vendeli.tgbot.annotations.internal.ExperimentalFeature"
"-opt-in=eu.vendeli.tgbot.annotations.internal.ExperimentalFeature",
)

private fun KotlinMultiplatformExtension.configureJvm() {
Expand Down
16 changes: 10 additions & 6 deletions buildSrc/src/main/kotlin/Kdokker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ abstract class Kdokker : DefaultTask() {
private val kdocRegex = Regex("\\n/\\*\\*.*\\*/", RegexOption.DOT_MATCHES_ALL)
private val NEWLINE = "\n"
private val apiFiles = project.layout.projectDirectory
.dir("src/commonMain/kotlin/eu/vendeli/tgbot/api").asFileTree.files
.dir("src/commonMain/kotlin/eu/vendeli/tgbot/api")
.asFileTree.files
private val typeFiles = project.layout.projectDirectory
.dir("src/commonMain/kotlin/eu/vendeli/tgbot/types").asFileTree.files.filter {
.dir("src/commonMain/kotlin/eu/vendeli/tgbot/types")
.asFileTree.files
.filter {
!it.path.contains("internal")
}
private fun File.isKotlinFile() = isFile && extension == "kt"
Expand All @@ -54,10 +57,11 @@ abstract class Kdokker : DefaultTask() {
else -> this[0].uppercase() + this.substring(1)
}

private fun String.snakeToCamelCase() = split('_').mapIndexed { i, it ->
if (i == 0) return@mapIndexed it
it.beginWithUpperCase()
}.joinToString("")
private fun String.snakeToCamelCase() = split('_')
.mapIndexed { i, it ->
if (i == 0) return@mapIndexed it
it.beginWithUpperCase()
}.joinToString("")

@TaskAction
fun updateKDoc() {
Expand Down
4 changes: 3 additions & 1 deletion buildSrc/src/main/kotlin/PublishingExt.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import org.gradle.api.model.ObjectFactory
import org.gradle.kotlin.dsl.property

open class PublishingExtension(factory: ObjectFactory) {
open class PublishingExtension(
factory: ObjectFactory,
) {
val name = factory.property<String>()
val description = factory.property<String>()
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ stately = "2.1.0"
kotlin = "2.1.0"
coroutines = "1.9.0"
dokka = "1.9.20"
kotlinter = "4.5.0"
kotlinter = "5.0.1"
deteKT = "1.23.7"
toml = "0.4.0"

Expand Down
1 change: 0 additions & 1 deletion helper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ detekt {
allRules = false
config.from(files("$rootDir/detekt.yml"))
}

1 change: 0 additions & 1 deletion ksp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,3 @@ detekt {
allRules = false
config.from(files("$rootDir/detekt.yml"))
}

2 changes: 1 addition & 1 deletion ksp/src/jvmMain/kotlin/eu/vendeli/ksp/ActivityProcessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class ActivityProcessor(
logger = logger,
idxPostfix = idxPostfix,
pkg = filePkg,
autoCleanClassData = autoCleanClassData
autoCleanClassData = autoCleanClassData,
)

collectCommandActivities(commandHandlerSymbols, context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,23 @@ object EnvConfigLoader : ConfigLoader {
)

val httpConfiguration = HttpConfiguration(
requestTimeoutMillis = EnvVar.get(DEFAULT_ENV_PREFIX + "HTTP_REQUEST_TIMEOUT_MILLIS") { Int.MAX_VALUE.toString() }
requestTimeoutMillis = EnvVar
.get(
DEFAULT_ENV_PREFIX + "HTTP_REQUEST_TIMEOUT_MILLIS",
) { Int.MAX_VALUE.toString() }
.toLong(),
connectTimeoutMillis = EnvVar.get(DEFAULT_ENV_PREFIX + "HTTP_CONNECT_TIMEOUT_MILLIS") { Int.MAX_VALUE.toString() }
connectTimeoutMillis = EnvVar
.get(
DEFAULT_ENV_PREFIX + "HTTP_CONNECT_TIMEOUT_MILLIS",
) { Int.MAX_VALUE.toString() }
.toLong(),
socketTimeoutMillis = EnvVar.get(DEFAULT_ENV_PREFIX + "HTTP_SOCKET_TIMEOUT_MILLIS") { Int.MAX_VALUE.toString() }
socketTimeoutMillis = EnvVar
.get(
DEFAULT_ENV_PREFIX + "HTTP_SOCKET_TIMEOUT_MILLIS",
) { Int.MAX_VALUE.toString() }
.toLong(),
maxRequestRetry = EnvVar.get(DEFAULT_ENV_PREFIX + "HTTP_MAX_REQUEST_RETRY") { "3" }.toInt(),
retryDelay = EnvVar.get(DEFAULT_ENV_PREFIX + "HTTP_RETRY_DELAY") { "3000" }.toLong()
retryDelay = EnvVar.get(DEFAULT_ENV_PREFIX + "HTTP_RETRY_DELAY") { "3000" }.toLong(),
)

val loggingConfiguration = LoggingConfiguration(
Expand All @@ -60,9 +69,13 @@ object EnvConfigLoader : ConfigLoader {
commandDelimiter = EnvVar.get(DEFAULT_ENV_PREFIX + "COMMAND_DELIMITER") { "?" }[0],
parametersDelimiter = EnvVar.get(DEFAULT_ENV_PREFIX + "PARAMETERS_DELIMITER") { "&" }[0],
parameterValueDelimiter = EnvVar.get(DEFAULT_ENV_PREFIX + "PARAMETER_VALUE_DELIMITER") { "=" }[0],
restrictSpacesInCommands = EnvVar.get(DEFAULT_ENV_PREFIX + "RESTRICT_SPACES_IN_COMMANDS") { "false" }
restrictSpacesInCommands = EnvVar
.get(DEFAULT_ENV_PREFIX + "RESTRICT_SPACES_IN_COMMANDS") { "false" }
.toBoolean(),
useIdentifierInGroupCommands = EnvVar.get(DEFAULT_ENV_PREFIX + "USE_IDENTIFIER_IN_GROUP_COMMANDS") { "false" }
useIdentifierInGroupCommands = EnvVar
.get(
DEFAULT_ENV_PREFIX + "USE_IDENTIFIER_IN_GROUP_COMMANDS",
) { "false" }
.toBoolean(),
)

Expand All @@ -76,7 +89,7 @@ object EnvConfigLoader : ConfigLoader {
logging = loggingConfiguration,
updatesListener = updatesListenerConfiguration,
commandParsing = commandParsingConfiguration,
throwExOnActionsFailure = throwExOnActionsFailure
throwExOnActionsFailure = throwExOnActionsFailure,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import eu.vendeli.tgbot.types.internal.configuration.CompleteConfig
import kotlinx.serialization.serializer
import net.peanuuutz.tomlkt.Toml

open class TomlConfigLoader(input: String) : ConfigLoader {
open class TomlConfigLoader(
input: String,
) : ConfigLoader {
private val toml = Toml.decodeFromString(serializer<CompleteConfig>(), input)
override val token: String = toml.token
override val commandsPackage: String? = toml.pckg
Expand Down
5 changes: 4 additions & 1 deletion ktgram-config-toml/src/jvmMain/kotlin/TelegramBotExt.jvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import java.nio.charset.Charset
fun TelegramBot.fromToml(fileName: String = "bot.toml") =
TelegramBot(
TomlConfigLoader(
javaClass.classLoader.getResourceAsStream(fileName)!!.readAllBytes().toString(Charset.defaultCharset()),
javaClass.classLoader
.getResourceAsStream(fileName)!!
.readAllBytes()
.toString(Charset.defaultCharset()),
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package eu.vendeli.ktgram.extutils

import eu.vendeli.tgbot.TelegramBot
import eu.vendeli.tgbot.interfaces.action.Action
import eu.vendeli.tgbot.types.User
import eu.vendeli.tgbot.types.chat.Chat
import eu.vendeli.tgbot.types.internal.Identifier
import eu.vendeli.tgbot.types.internal.getOrNull
import eu.vendeli.tgbot.utils.TgException

private val DEFAULT_FAILURE_ACTION: suspend () -> Nothing = { throw TgException("Failed to process response") }

private suspend fun <R> Action<R>.sendAnd(
to: Identifier,
bot: TelegramBot,
onFailure: suspend () -> Nothing = DEFAULT_FAILURE_ACTION,
block: suspend R.() -> Unit,
) {
val result = when (to) {
is Identifier.String -> {
sendReturning(to.get, bot).getOrNull()
}

is Identifier.Long -> {
sendReturning(to.get, bot).getOrNull()
}
} ?: onFailure()
block(result)
}

suspend fun <R> Action<R>.sendAnd(
to: Long,
bot: TelegramBot,
onFailure: suspend () -> Nothing = DEFAULT_FAILURE_ACTION,
block: suspend R.() -> Unit,
) = sendAnd(Identifier.from(to), bot, onFailure, block)

suspend fun <R> Action<R>.sendAnd(
to: String,
bot: TelegramBot,
onFailure: suspend () -> Nothing = DEFAULT_FAILURE_ACTION,
block: suspend R.() -> Unit,
) = sendAnd(Identifier.from(to), bot, onFailure, block)

suspend fun <R> Action<R>.sendAnd(
to: Chat,
bot: TelegramBot,
onFailure: suspend () -> Nothing = DEFAULT_FAILURE_ACTION,
block: suspend R.() -> Unit,
) = sendAnd(Identifier.from(to), bot, onFailure, block)

suspend fun <R> Action<R>.sendAnd(
to: User,
bot: TelegramBot,
onFailure: suspend () -> Nothing = DEFAULT_FAILURE_ACTION,
block: suspend R.() -> Unit,
) = sendAnd(Identifier.from(to), bot, onFailure, block)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import java.io.File
import java.security.KeyStore
import java.security.PrivateKey


suspend fun serveWebhook(
wait: Boolean = true,
serverBuilder: suspend ServerBuilder.() -> Unit = {},
Expand Down Expand Up @@ -84,4 +83,3 @@ suspend fun serveWebhook(
}
}.start(wait)
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eu.vendeli.ktor.starter

import eu.vendeli.tgbot.TelegramBot
import eu.vendeli.tgbot.annotations.internal.KtGramInternal
import eu.vendeli.tgbot.types.internal.configuration.HttpConfiguration
import eu.vendeli.tgbot.types.internal.configuration.LoggingConfiguration
import eu.vendeli.tgbot.utils.getConfiguredHttpClient
Expand All @@ -23,10 +22,10 @@ class ServerBuilder internal constructor() {
server = ManualConfiguration().apply(configurator)
}


suspend fun declareBot(block: BotConfiguration.() -> Unit) = BotConfiguration().apply(block).also { cfg ->
val client = if (shareHttpClient) httpClient ?: getConfiguredHttpClient(
HttpConfiguration(), LoggingConfiguration(),
HttpConfiguration(),
LoggingConfiguration(),
) else null

botInstances[cfg.token] = TelegramBot(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import kotlin.reflect.KClass

@Configuration
open class SpringClassManager(
private val applicationContext: ApplicationContext
private val applicationContext: ApplicationContext,
) : ClassManager {
override fun getInstance(kClass: KClass<*>, vararg initParams: Any?): Any =
applicationContext.getBean(kClass.java, *initParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.bind.ConstructorBinding

@ConfigurationProperties(prefix = "ktgram")
data class TgConfigProperties @ConstructorBinding constructor(
val autoStartPolling: Boolean = true,
val shareHttpClient: Boolean = false,
val bot: List<BotProperties>,
) {
data class BotProperties(
val token: String,
val pckg: String? = null,
val identifier: String = "KtGram",
)
}
data class TgConfigProperties
@ConstructorBinding
constructor(
val autoStartPolling: Boolean = true,
val shareHttpClient: Boolean = false,
val bot: List<BotProperties>,
) {
data class BotProperties(
val token: String,
val pckg: String? = null,
val identifier: String = "KtGram",
)
}
4 changes: 2 additions & 2 deletions telegram-bot/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ tasks {
withType<Test> { useJUnitPlatform() }
named("build") { dependsOn("kspCommonMainKotlinMetadata") }
dokkaHtml.configure {
outputDirectory = layout.buildDirectory.asFile.orNull?.resolve("dokka")
outputDirectory = layout.buildDirectory.asFile.orNull
?.resolve("dokka")
dokkaSourceSets {
named("commonMain") { sourceRoots.setFrom(project.projectDir.resolve("src/commonMain/kotlin")) }
named("jvmMain") { sourceRoots.setFrom(project.projectDir.resolve("src/jvmMain/kotlin")) }
Expand Down Expand Up @@ -137,4 +138,3 @@ kover.reports.filters.excludes {
"eu.vendeli.tgbot.implementations.EnvConfigLoader*",
)
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import eu.vendeli.tgbot.types.ReactionType
import eu.vendeli.tgbot.utils.builders.ListingBuilder
import eu.vendeli.tgbot.utils.encodeWith
import eu.vendeli.tgbot.utils.getReturnType
import eu.vendeli.tgbot.utils.serde.DynamicLookupSerializer
import eu.vendeli.tgbot.utils.toJsonElement
import kotlinx.serialization.builtins.ListSerializer

Expand All @@ -24,7 +23,7 @@ class SetMessageReactionAction(

init {
parameters["message_id"] = messageId.toJsonElement()
if (reaction != null) parameters["reaction"] = reaction.encodeWith(ListSerializer(DynamicLookupSerializer))
if (reaction != null) parameters["reaction"] = reaction.encodeWith(ListSerializer(ReactionType.serializer()))
if (isBig != null) parameters["is_big"] = messageId.toJsonElement()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import eu.vendeli.tgbot.types.internal.options.AnswerInlineQueryOptions
import eu.vendeli.tgbot.utils.builders.ListingBuilder
import eu.vendeli.tgbot.utils.encodeWith
import eu.vendeli.tgbot.utils.getReturnType
import eu.vendeli.tgbot.utils.serde.DynamicLookupSerializer
import eu.vendeli.tgbot.utils.toJsonElement
import kotlinx.serialization.builtins.ListSerializer

Expand All @@ -27,7 +26,7 @@ class AnswerInlineQueryAction(

init {
parameters["inline_query_id"] = inlineQueryId.toJsonElement()
parameters["results"] = results.encodeWith(ListSerializer(DynamicLookupSerializer))
parameters["results"] = results.encodeWith(ListSerializer(InlineQueryResult.serializer()))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import eu.vendeli.tgbot.types.SentWebAppMessage
import eu.vendeli.tgbot.types.inline.InlineQueryResult
import eu.vendeli.tgbot.utils.encodeWith
import eu.vendeli.tgbot.utils.getReturnType
import eu.vendeli.tgbot.utils.serde.DynamicLookupSerializer
import eu.vendeli.tgbot.utils.toJsonElement

@TgAPI
Expand All @@ -22,7 +21,7 @@ class AnswerWebAppQueryAction(

init {
parameters["web_app_query_id"] = webAppQueryId.toJsonElement()
parameters["result"] = result.encodeWith(DynamicLookupSerializer)
parameters["result"] = result.encodeWith(InlineQueryResult.serializer())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import eu.vendeli.tgbot.types.internal.options.SavePreparedInlineMessageOptions
import eu.vendeli.tgbot.types.msg.PreparedInlineMessage
import eu.vendeli.tgbot.utils.encodeWith
import eu.vendeli.tgbot.utils.getReturnType
import eu.vendeli.tgbot.utils.serde.DynamicLookupSerializer
import eu.vendeli.tgbot.utils.toJsonElement

@TgAPI
Expand All @@ -26,7 +25,7 @@ class SavePreparedInlineMessageAction(

init {
parameters["user_id"] = userId.toJsonElement()
parameters["result"] = result.encodeWith(DynamicLookupSerializer)
parameters["result"] = result.encodeWith(InlineQueryResult.serializer())
}
}

Expand Down
Loading

0 comments on commit ebba15d

Please sign in to comment.