1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-27 09:45:46 +00:00

Compare commits

..

24 Commits

Author SHA1 Message Date
53800d49bf small rework in ExceptionsOnlyLimiter 2020-11-11 11:23:24 +06:00
d83e3eb10a add handling of 429 status 2020-11-11 11:15:19 +06:00
66b4d06064 limiter rework 2020-11-11 10:23:20 +06:00
4fab01b2a2 update micro_utils 2020-11-11 10:15:06 +06:00
b81086c4bb start 0.30.3 2020-11-11 10:14:10 +06:00
d776071cac Update build.gradle 2020-11-11 01:32:25 +06:00
5f33d05deb Update extensions utils dependencies 2020-11-11 01:31:28 +06:00
912cc7217c Update extensions api dependencies 2020-11-11 01:30:31 +06:00
96e00f6e31 Merge pull request #207 from InsanusMokrassar/0.30.2
0.30.2
2020-11-10 21:52:37 +06:00
f8ea5f9515 fix in changelog 2020-11-10 21:45:07 +06:00
9f11c4f1c4 update ktor 2020-11-10 20:56:11 +06:00
9c91980d5d webhook fixes 2020-11-10 20:44:39 +06:00
7376eb5b10 start 0.30.2 2020-11-10 20:01:22 +06:00
6654f27f9d Merge pull request #202 from InsanusMokrassar/0.30.1
0.30.1
2020-11-09 15:16:26 +06:00
d29acce417 add suppressing of unused in EntitiesBuilder 2020-11-09 15:14:48 +06:00
f0f18209f3 a little bit improve EntitiesBuilder 2020-11-09 15:12:57 +06:00
324018a0f6 update publication scripts 2020-11-09 14:45:29 +06:00
b621325e92 update version of microutils and changelog 2020-11-09 08:37:30 +06:00
43e92555c2 Merge pull request #203 from Djaler/entities-dsl
Add builder-style dsl for text sources
2020-11-09 08:26:44 +06:00
Kirill Romanov
5f1ca51e60 Add builder-style dsl for text sources 2020-11-08 23:12:32 +03:00
83edda2dfe add link to bot template 2020-11-08 18:58:52 +06:00
1974c20229 start 0.30.1 2020-11-08 12:07:14 +06:00
499d9b1791 Update README.md 2020-11-08 00:03:41 +06:00
6caa7dd428 Merge pull request #163 from InsanusMokrassar/0.30.0
0.30.0
2020-11-07 23:00:35 +06:00
27 changed files with 338 additions and 134 deletions

View File

@@ -1,5 +1,38 @@
# TelegramBotAPI changelog
## 0.30.3
* `Common`:
* `Version`:
* `MicroUtils`: `0.3.0` -> `0.3.1`
* `Core`:
* New type of requests exceptions `TooMuchRequestsException`. In fact it will be rare case when you will get this
exception
* `EmptyLimiter` has been renamed to `ExceptionsOnlyLimiter` and currently will stop requests after
`TooMuchRequestsException` happen until retry time is actual
* Now `ExceptionsOnlyLimiter` (previously `EmptyLimiter`) is a class
* `AbstractRequestCallFactory` currently will not look at the response and wait if it have `RetryAfter` error. New
behaviour aimed on delegating of this work to `RequestsLimiter`
## 0.30.2
* `Common`:
* `Version`:
* `Ktor`: `1.4.1` -> `1.4.2`
* `Core`:
* New sealed class `SetWebhookRequest` which can be used in `SetWebhook` requests
* `Utils`:
* Extensions `setWebhookInfoAndStartListenWebhooks` has been united in one extension with `SetWebhookRequest`
incoming parameter
## 0.30.1
* `Common`:
* `Version`:
* `MicroUtils`: `0.2.7` -> `0.3.0`
* `Utils`:
* Builder-style DSL for text sources - `buildEntities` (thanks to [djaler](https://github.com/djaler))
## 0.30.0 Bot API 5.0
**THIS UPDATE CONTAINS A LOT OF BREAKING CHANGES. PLEASE, BE CAREFUL ON UPGRADING OF YOUR PROJECT**

View File

@@ -2,7 +2,7 @@
| Common info | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI.svg?branch=master)](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|
| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Useful links | [![Chat in Telegram](badges/chat.svg)](https://t.me/InMoTelegramBotAPI) [![KDocs](badges/kdocs.svg)](https://tgbotapi.inmo.dev/docs/index.html) [Examples](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/), [Mini tutorial](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
| Useful links | [![Chat in Telegram](badges/chat.svg)](https://t.me/InMoTelegramBotAPI) [![Create bot](badges/template.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template/generate) [![KDocs](badges/kdocs.svg)](https://tgbotapi.inmo.dev/docs/index.html) [Examples](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/), [Mini tutorial](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
| TelegramBotAPI Core status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.core/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.core/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core) |
| TelegramBotAPI Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api) |
| TelegramBotAPI Util Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/images/download.svg)](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils) |

20
badges/template.svg Normal file
View File

@@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="104" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="a">
<rect width="104" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#555" d="M0 0h65v20H0z"/>
<path fill="#007ec6" d="M35 0h69v20H35z"/>
<path fill="url(#b)" d="M0 0h104v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
<text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Bot</text>
<text x="175" y="140" transform="scale(.1)">Bot</text>
<text x="690" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Template</text>
<text x="690" y="140" transform="scale(.1)">Template</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1016 B

View File

@@ -10,14 +10,14 @@ kotlin_coroutines_version=1.4.1
kotlin_serialisation_runtime_version=1.0.1
klock_version=1.12.1
uuid_version=0.2.2
ktor_version=1.4.1
ktor_version=1.4.2
micro_utils_version=0.2.7
micro_utils_version=0.3.1
javax_activation_version=1.1.1
library_group=dev.inmo
library_version=0.30.0
library_version=0.30.3
gradle_bintray_plugin_version=1.8.5
github_release_plugin_version=2.2.12

View File

@@ -10,7 +10,7 @@ moments are describing by official [Telegram Bot API](https://core.telegram.org/
## Compatibility
This version compatible with [4th of June 2020 update of TelegramBotAPI (version 4.9)](https://core.telegram.org/bots/api#june-4-2020).
This version compatible with [4th of November 2020 update of TelegramBotAPI (version 5.0)](https://core.telegram.org/bots/api#november-4-2020).
There is only one exception of implemented functionality - Telegram Passport API, which was presented in
[August 2018 update of TelegramBotAPI](https://core.telegram.org/bots/api-changelog#august-27-2018) update. It will be implemented
as soon as possible.

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Core","description":"Library for Object-Oriented and type-safe work with Telegram Bot API","url":"https://insanusmokrassar.github.io/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]},"type":"Multiplatform"}
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Core","description":"Library for Object-Oriented and type-safe work with Telegram Bot API","url":"https://insanusmokrassar.github.io/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}

View File

@@ -27,6 +27,7 @@ bintray {
}
publish = true
override = true
pkg {
repo = "TelegramBotAPI"

View File

@@ -4,8 +4,7 @@ import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.Ktor.base.*
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.bot.settings.limiters.EmptyLimiter
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
import dev.inmo.tgbotapi.bot.settings.limiters.*
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.utils.*
@@ -19,7 +18,7 @@ class KtorRequestsExecutor(
client: HttpClient = HttpClient(),
callsFactories: List<KtorCallFactory> = emptyList(),
excludeDefaultFactories: Boolean = false,
private val requestsLimiter: RequestLimiter = EmptyLimiter,
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
private val jsonFormatter: Json = nonstrictJsonFormat
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
private val callsFactories: List<KtorCallFactory> = callsFactories.run {

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.bot.Ktor.base
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.requests.GetUpdates
@@ -51,23 +52,17 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
val content = response.receive<String>()
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
return (responseObject.result?.let {
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
} ?: responseObject.parameters?.let {
val error = it.error
if (error is RetryAfterError) {
delay(error.leftToRetry)
makeCall(client, urlsKeeper, request, jsonFormatter)
} else {
null
}
} ?: response.let {
throw newRequestException(
responseObject,
content,
"Can't get result object from $content"
)
})
return safely {
(responseObject.result?.let {
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
} ?: response.let {
throw newRequestException(
responseObject,
content,
"Can't get result object from $content"
)
})
}
}
}

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.bot.exceptions
import dev.inmo.tgbotapi.types.Response
import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.types.*
import io.ktor.utils.io.errors.IOException
fun newRequestException(
@@ -16,6 +17,13 @@ fun newRequestException(
description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause)
description.contains("PHOTO_INVALID_DIMENSIONS") -> InvalidPhotoDimensionsException(response, plainAnswer, message, cause)
description.contains("wrong file identifier") -> WrongFileIdentifierException(response, plainAnswer, message, cause)
description.contains("Too Many Requests") -> TooMuchRequestsException(
(response.parameters ?.error as? RetryAfterError) ?: RetryAfterError(60, DateTime.now().unixMillisLong),
response,
plainAnswer,
message,
cause
)
else -> null
}
} ?: CommonRequestException(response, plainAnswer, message, cause)
@@ -49,3 +57,6 @@ class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, m
class WrongFileIdentifierException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause)
class TooMuchRequestsException(val retryAfter: RetryAfterError, response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
RequestException(response, plainAnswer, message, cause)

View File

@@ -1,5 +0,0 @@
package dev.inmo.tgbotapi.bot.settings.limiters
object EmptyLimiter : RequestLimiter {
override suspend fun <T> limit(block: suspend () -> T): T = block()
}

View File

@@ -0,0 +1,65 @@
package dev.inmo.tgbotapi.bot.settings.limiters
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.exceptions.TooMuchRequestsException
import dev.inmo.tgbotapi.types.*
import io.ktor.client.features.ClientRequestException
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
/**
* This limiter will limit requests only after getting a [RetryAfterError] or [ClientRequestException] with
* [HttpStatusCode.TooManyRequests] status code. Important thing is that in case if some of block has been blocked, all
* the others will wait until it will be possible to be called
*
* @param defaultTooManyRequestsDelay This parameter will be used in case of getting [ClientRequestException] with
* [HttpStatusCode.TooManyRequests] as a parameter for delay like it would be [TooMuchRequestsException]. The reason of
* it is that in [ClientRequestException] there is no information about required delay between requests
*/
class ExceptionsOnlyLimiter(
private val defaultTooManyRequestsDelay: MilliSeconds = 1000L
) : RequestLimiter {
private val lockState = MutableStateFlow(false)
private suspend fun lock(timeMillis: MilliSeconds) {
try {
safely {
lockState.emit(true)
delay(timeMillis)
}
} finally {
lockState.emit(false)
}
}
override suspend fun <T> limit(block: suspend () -> T): T {
while (true) {
lockState.first { !it }
val result = safely({
when (it) {
is TooMuchRequestsException -> {
lock(it.retryAfter.leftToRetry)
Result.failure(it)
}
is ClientRequestException -> {
if (it.response.status == HttpStatusCode.TooManyRequests) {
lock(defaultTooManyRequestsDelay)
} else {
throw it
}
Result.failure(it)
}
else -> throw it
}
}) {
Result.success(block())
}
if (result.isSuccess) {
return result.getOrNull()!!
}
}
}
}
@Deprecated("Renamed", ReplaceWith("ExceptionsOnlyLimiter", "dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter"))
typealias EmptyLimiter = ExceptionsOnlyLimiter

View File

@@ -1,8 +1,7 @@
package dev.inmo.tgbotapi.requests.webhook
import dev.inmo.tgbotapi.requests.abstracts.*
import dev.inmo.tgbotapi.requests.send.media.base.DataRequest
import dev.inmo.tgbotapi.requests.send.media.base.MultipartRequestImpl
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
@@ -13,14 +12,15 @@ private fun correctWebhookUrl(sourceUrl: String) = if (sourceUrl.contains("://")
"https://$sourceUrl"
}
fun SetWebhook(
sealed class SetWebhookRequest : Request<Boolean>
class MultipartSetWebhookRequest(
url: String,
certificate: MultipartFile,
ipAddress: String? = null,
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): MultipartRequestImpl<SetWebhook, Map<String, MultipartFile>, Boolean> = MultipartRequestImpl(
) : SetWebhookRequest(), MultipartRequest<Boolean> by MultipartRequestImpl(
SetWebhook(
correctWebhookUrl(url),
null as String?,
@@ -32,6 +32,22 @@ fun SetWebhook(
mapOf(certificateField to certificate)
)
fun SetWebhook(
url: String,
certificate: MultipartFile,
ipAddress: String? = null,
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): MultipartSetWebhookRequest = MultipartSetWebhookRequest(
correctWebhookUrl(url),
certificate,
ipAddress,
maxAllowedConnections,
allowedUpdates,
dropPendingUpdates
)
fun SetWebhook(
url: String,
certificate: FileId,
@@ -63,7 +79,7 @@ fun SetWebhook(
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): Request<Boolean> = when (certificate) {
) = when (certificate) {
is MultipartFile -> SetWebhook(correctWebhookUrl(url), certificate as MultipartFile, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates)
is FileId -> SetWebhook(correctWebhookUrl(url), certificate as FileId, ipAddress, maxAllowedConnections, allowedUpdates, dropPendingUpdates)
}
@@ -82,7 +98,7 @@ fun SetWebhook(
maxAllowedConnections: Int? = null,
allowedUpdates: List<String>? = null,
dropPendingUpdates: Boolean? = null
): Request<Boolean> = SetWebhook(
) = SetWebhook(
correctWebhookUrl(url),
null,
ipAddress,
@@ -112,7 +128,7 @@ data class SetWebhook internal constructor(
val allowedUpdates: List<String>? = null,
@SerialName(dropPendingUpdatesField)
val dropPendingUpdates: Boolean? = null
) : DataRequest<Boolean> {
) : SetWebhookRequest(), DataRequest<Boolean> {
override fun method(): String = "setWebhook"
override val resultDeserializer: DeserializationStrategy<Boolean>
get() = Boolean.serializer()

View File

@@ -28,6 +28,7 @@ typealias GooglePlaceId = String
typealias GooglePlaceType = String
typealias Seconds = Int
typealias MilliSeconds = Long
typealias LongSeconds = Long
typealias Meters = Float

View File

@@ -5,7 +5,7 @@ import com.soywiz.klock.DateTime
sealed class RequestError
data class RetryAfterError(
val seconds: Long,
val seconds: Seconds,
val startCountingMillis: Long
) : RequestError() {
val canContinue = (seconds * 1000L) + startCountingMillis

View File

@@ -8,7 +8,7 @@ data class ResponseParametersRaw(
@SerialName("migrate_to_chat_id")
private val migrateToChatId: ChatId? = null,
@SerialName("retry_after")
private val retryAfter: Long? = null
private val retryAfter: Seconds? = null
) {
@Transient
private val createTime: Long = DateTime.now().unixMillisLong

View File

@@ -40,11 +40,7 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
if ((project.hasProperty('RELEASE_MODE') && project.property('RELEASE_MODE') == "true") || System.getenv('RELEASE_MODE') == "true") {
api "${project.group}:tgbotapi.core:$library_version"
} else {
api project(":tgbotapi.core")
}
api project(":tgbotapi.core")
}
}
}

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Extensions for API","description":"API extensions which provide work with RequestsExecutor of TelegramBotAPI almost like it is described in original Telegram Bot API reference","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-api","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]},"type":"Multiplatform"}
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Extensions for API","description":"API extensions which provide work with RequestsExecutor of TelegramBotAPI almost like it is described in original Telegram Bot API reference","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-api","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}

View File

@@ -27,6 +27,7 @@ bintray {
}
publish = true
override = true
pkg {
repo = "TelegramBotAPI"

View File

@@ -40,11 +40,7 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
if ((project.hasProperty('RELEASE_MODE') && project.property('RELEASE_MODE') == "true") || System.getenv('RELEASE_MODE') == "true") {
api "${project.group}:tgbotapi.core:$library_version"
} else {
api project(":tgbotapi.core")
}
api project(":tgbotapi.core")
}
}
}

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Utility Extensions","description":"Util extensions for more useful work with updates and other things","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-utils","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]},"type":"Multiplatform"}
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API Utility Extensions","description":"Util extensions for more useful work with updates and other things","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI-extensions-utils","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}

View File

@@ -27,6 +27,7 @@ bintray {
}
publish = true
override = true
pkg {
repo = "TelegramBotAPI"

View File

@@ -0,0 +1,140 @@
@file:Suppress("NOTHING_TO_INLINE", "unused")
package dev.inmo.tgbotapi.extensions.utils.formatting
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.types.User
fun buildEntities(init: EntitiesBuilder.() -> Unit): List<TextSource> = EntitiesBuilder().apply(init).build()
/**
* This builder can be used to provide building of [TextSource]s [List]
*
* @see buildEntities
*/
class EntitiesBuilder internal constructor(
private val entitiesList: MutableList<TextSource> = mutableListOf()
) {
/**
* It is not safe field which contains potentially changeable [List]
*/
val entities: List<TextSource>
get() = entitiesList
/**
* @return New immutable list which will be deattached from this builder
*/
fun build(): List<TextSource> = entities.toList()
fun add(source: TextSource) { entitiesList.add(source) }
operator fun TextSource.unaryPlus() = add(this)
operator fun List<TextSource>.unaryPlus() = entitiesList.addAll(this)
operator fun invoke(vararg source: TextSource) = entitiesList.addAll(source)
operator fun String.unaryPlus() {
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.regular(this))
}
}
inline fun EntitiesBuilder.bold(parts: List<TextSource>) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(parts))
inline fun EntitiesBuilder.bold(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(*parts))
inline fun EntitiesBuilder.bold(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(text))
inline fun EntitiesBuilder.botCommand(command: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.botCommand(command))
inline fun EntitiesBuilder.cashTag(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(parts))
inline fun EntitiesBuilder.cashTag(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(*parts))
inline fun EntitiesBuilder.cashTag(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(text))
inline fun EntitiesBuilder.code(code: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.code(code))
inline fun EntitiesBuilder.email(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(parts))
inline fun EntitiesBuilder.email(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(*parts))
inline fun EntitiesBuilder.email(emailAddress: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(emailAddress))
inline fun EntitiesBuilder.hashtag(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(parts))
inline fun EntitiesBuilder.hashtag(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(*parts))
inline fun EntitiesBuilder.hashtag(hashtag: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(hashtag))
inline fun EntitiesBuilder.italic(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(parts))
inline fun EntitiesBuilder.italic(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(*parts))
inline fun EntitiesBuilder.italic(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(text))
inline fun EntitiesBuilder.mention(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(parts))
inline fun EntitiesBuilder.mention(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(*parts))
inline fun EntitiesBuilder.mention(whoToMention: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(whoToMention))
inline fun EntitiesBuilder.mention(parts: List<TextSource>, user: User) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(parts, user))
inline fun EntitiesBuilder.mention(user: User, vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(user, *parts))
inline fun EntitiesBuilder.mention(text: String, user: User) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(text, user))
inline fun EntitiesBuilder.phone(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(parts))
inline fun EntitiesBuilder.phone(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(*parts))
inline fun EntitiesBuilder.phone(number: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(number))
inline fun EntitiesBuilder.pre(code: String, language: String?) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.pre(code, language))
inline fun EntitiesBuilder.regular(text: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.regular(text))
inline fun EntitiesBuilder.strikethrough(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(parts))
inline fun EntitiesBuilder.strikethrough(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(*parts))
inline fun EntitiesBuilder.strikethrough(text: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(text))
inline fun EntitiesBuilder.link(text: String, url: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.link(text, url))
inline fun EntitiesBuilder.link(url: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.link(url))
inline fun EntitiesBuilder.underline(parts: List<TextSource>) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(parts))
inline fun EntitiesBuilder.underline(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(*parts))
inline fun EntitiesBuilder.underline(text: String) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(text))

View File

@@ -5,10 +5,7 @@ import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.extensions.utils.nonstrictJsonFormat
import dev.inmo.tgbotapi.extensions.utils.updates.flowsUpdatesFilter
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.media.base.MultipartRequestImpl
import dev.inmo.tgbotapi.requests.webhook.SetWebhook
import dev.inmo.tgbotapi.requests.webhook.SetWebhookRequest
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.types.update.abstracts.UpdateDeserializationStrategy
import dev.inmo.tgbotapi.updateshandlers.*
@@ -67,7 +64,7 @@ fun Route.includeWebhookHandlingInRouteWithFlows(
)
/**
* Setting up ktor server, set webhook info via [SetWebhook] request.
* Setting up ktor server
*
* @param listenPort port which will be listen by bot
* @param listenRoute address to listen by bot. If null - will be set up in root of host
@@ -119,27 +116,8 @@ fun startListenWebhooks(
}
}
private suspend fun RequestsExecutor.internalSetWebhookInfoAndStartListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
setWebhookRequest: Request<Boolean>,
exceptionsHandler: ExceptionHandler<Unit> = {},
listenHost: String = "0.0.0.0",
listenRoute: String? = null,
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
): ApplicationEngine {
return try {
execute(setWebhookRequest)
startListenWebhooks(listenPort, engineFactory, exceptionsHandler, listenHost, listenRoute, privateKeyConfig, scope, block)
} catch (e: Exception) {
throw e
}
}
/**
* Setting up ktor server, set webhook info via [SetWebhook] request.
* Setting up ktor server, set webhook info via [SetWebhookRequest] request.
*
* @param listenPort port which will be listen by bot
* @param listenRoute address to listen by bot
@@ -153,55 +131,16 @@ private suspend fun RequestsExecutor.internalSetWebhookInfoAndStartListenWebhook
suspend fun RequestsExecutor.setWebhookInfoAndStartListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
setWebhookRequest: SetWebhook,
setWebhookRequest: SetWebhookRequest,
exceptionsHandler: ExceptionHandler<Unit> = {},
listenHost: String = "0.0.0.0",
listenRoute: String = "/",
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
): ApplicationEngine = internalSetWebhookInfoAndStartListenWebhooks(
listenPort,
engineFactory,
setWebhookRequest as Request<Boolean>,
exceptionsHandler,
listenHost,
listenRoute,
privateKeyConfig,
scope,
block
)
/**
* Setting up ktor server, set webhook info via [SetWebhook] request.
*
* @param listenPort port which will be listen by bot
* @param listenRoute address to listen by bot
* @param scope Scope which will be used for
*
* @see dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
* @see UpdatesFilter
* @see UpdatesFilter.asUpdateReceiver
*/
@Suppress("unused")
suspend fun RequestsExecutor.setWebhookInfoAndStartListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
setWebhookRequest: MultipartRequestImpl<SetWebhook, Map<String, MultipartFile>, Boolean>,
exceptionsHandler: ExceptionHandler<Unit> = {},
listenHost: String = "0.0.0.0",
listenRoute: String? = null,
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
): ApplicationEngine = internalSetWebhookInfoAndStartListenWebhooks(
listenPort,
engineFactory,
setWebhookRequest as Request<Boolean>,
exceptionsHandler,
listenHost,
listenRoute,
privateKeyConfig,
scope,
block
)
): ApplicationEngine = try {
execute(setWebhookRequest)
startListenWebhooks(listenPort, engineFactory, exceptionsHandler, listenHost, listenRoute, privateKeyConfig, scope, block)
} catch (e: Exception) {
throw e
}

View File

@@ -40,15 +40,9 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
if ((project.hasProperty('RELEASE_MODE') && project.property('RELEASE_MODE') == "true") || System.getenv('RELEASE_MODE') == "true") {
api "${project.group}:tgbotapi.core:$library_version"
api "${project.group}:tgbotapi.extensions.api:$library_version"
api "${project.group}:tgbotapi.extensions.utils:$library_version"
} else {
api project(":tgbotapi.core")
api project(":tgbotapi.extensions.api")
api project(":tgbotapi.extensions.utils")
}
api project(":tgbotapi.core")
api project(":tgbotapi.extensions.api")
api project(":tgbotapi.extensions.utils")
}
}
}

View File

@@ -1 +1 @@
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API","description":"This project just include all subproject of TelegramBotAPI","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]},"type":"Multiplatform"}
{"bintrayConfig":{"repo":"TelegramBotAPI","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/TelegramBotAPI","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"Telegram Bot API","description":"This project just include all subproject of TelegramBotAPI","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}]}}

View File

@@ -27,6 +27,7 @@ bintray {
}
publish = true
override = true
pkg {
repo = "TelegramBotAPI"