mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 16:23:48 +00:00
commit
6bdd17a186
10
CHANGELOG.md
10
CHANGELOG.md
@ -27,6 +27,16 @@ must be regular text
|
|||||||
* `RequestsExecutor#executeAsync(Request, CoroutineScope)` now will return `Deferred` for cases when you need result
|
* `RequestsExecutor#executeAsync(Request, CoroutineScope)` now will return `Deferred` for cases when you need result
|
||||||
* `RequestsExecutor#executeUnsafe` will automatically retry request if it was unsuccessful and retries > 0
|
* `RequestsExecutor#executeUnsafe` will automatically retry request if it was unsuccessful and retries > 0
|
||||||
|
|
||||||
|
### 0.9.3
|
||||||
|
|
||||||
|
* `KtorRequestsExecutor` now can use custom `JSON` string formatter (by default - non strict)
|
||||||
|
* `ResponseParameters` renamed to `Response`
|
||||||
|
* Add `RequestError` sealed class and described in documentation known errors
|
||||||
|
* Add `ResponseParametersRaw` which can create error based on input parameters
|
||||||
|
* Add `parameters` field in `Response` and remove useless fields from `Response`
|
||||||
|
* Add `leftToRetry` parameter in `RetryAfterError`
|
||||||
|
* Add handling of `RetryAfterError` in `KtorRequestsExecutor`
|
||||||
|
|
||||||
### 0.8.5
|
### 0.8.5
|
||||||
|
|
||||||
* Add extension `String#toMarkdown`
|
* Add extension `String#toMarkdown`
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
project.version = "0.9.2"
|
project.version = "0.9.3"
|
||||||
project.group = "com.github.insanusmokrassar"
|
project.group = "com.github.insanusmokrassar"
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
@ -7,12 +7,14 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestException
|
|||||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.EmptyLimiter
|
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.EmptyLimiter
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.RequestLimiter
|
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.RequestLimiter
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters
|
import com.github.insanusmokrassar.TelegramBotAPI.types.Response
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.RetryAfterError
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.call.HttpClientCall
|
import io.ktor.client.call.HttpClientCall
|
||||||
import io.ktor.client.engine.HttpClientEngine
|
import io.ktor.client.engine.HttpClientEngine
|
||||||
import io.ktor.client.engine.okhttp.OkHttp
|
import io.ktor.client.engine.okhttp.OkHttp
|
||||||
import io.ktor.util.cio.toByteArray
|
import io.ktor.util.cio.toByteArray
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.io.charsets.Charset
|
import kotlinx.io.charsets.Charset
|
||||||
import kotlinx.serialization.json.JSON
|
import kotlinx.serialization.json.JSON
|
||||||
|
|
||||||
@ -22,7 +24,8 @@ class KtorRequestsExecutor(
|
|||||||
hostUrl: String = "https://api.telegram.org",
|
hostUrl: String = "https://api.telegram.org",
|
||||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||||
excludeDefaultFactories: Boolean = false,
|
excludeDefaultFactories: Boolean = false,
|
||||||
private val requestsLimiter: RequestLimiter = EmptyLimiter
|
private val requestsLimiter: RequestLimiter = EmptyLimiter,
|
||||||
|
private val jsonFormatter: JSON = JSON.nonstrict
|
||||||
) : BaseRequestsExecutor(token, hostUrl) {
|
) : BaseRequestsExecutor(token, hostUrl) {
|
||||||
constructor(
|
constructor(
|
||||||
token: String,
|
token: String,
|
||||||
@ -59,11 +62,19 @@ class KtorRequestsExecutor(
|
|||||||
throw IllegalArgumentException("Can't execute request: $request")
|
throw IllegalArgumentException("Can't execute request: $request")
|
||||||
}
|
}
|
||||||
val content = call.response.content.toByteArray().toString(Charset.defaultCharset())
|
val content = call.response.content.toByteArray().toString(Charset.defaultCharset())
|
||||||
val responseObject = JSON.parse(
|
val responseObject = jsonFormatter.parse(
|
||||||
ResponseParameters.serializer(request.resultSerializer()),
|
Response.serializer(request.resultSerializer()),
|
||||||
content
|
content
|
||||||
)
|
)
|
||||||
responseObject.result ?: call.let {
|
responseObject.result ?: responseObject.parameters ?.let {
|
||||||
|
val error = it.error
|
||||||
|
if (error is RetryAfterError) {
|
||||||
|
delay(error.leftToRetry)
|
||||||
|
execute(request)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} ?: call.let {
|
||||||
throw RequestException(
|
throw RequestException(
|
||||||
responseObject,
|
responseObject,
|
||||||
"Can't get result object"
|
"Can't get result object"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.bot
|
package com.github.insanusmokrassar.TelegramBotAPI.bot
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters
|
import com.github.insanusmokrassar.TelegramBotAPI.types.Response
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
class RequestException(
|
class RequestException(
|
||||||
val response: ResponseParameters<*>,
|
val response: Response<*>,
|
||||||
message: String? = null,
|
message: String? = null,
|
||||||
cause: Throwable? = null
|
cause: Throwable? = null
|
||||||
) : IOException(
|
) : IOException(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts
|
package com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts
|
||||||
|
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters
|
import com.github.insanusmokrassar.TelegramBotAPI.types.Response
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls
|
import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@ -15,6 +15,6 @@ interface Request<T: Any> {
|
|||||||
fun <T : Any> StringFormat.extractResult(
|
fun <T : Any> StringFormat.extractResult(
|
||||||
from: String,
|
from: String,
|
||||||
dataSerializer: KSerializer<T>
|
dataSerializer: KSerializer<T>
|
||||||
): ResponseParameters<T> {
|
): Response<T> {
|
||||||
return parse(ResponseParameters.serializer(dataSerializer), from)
|
return parse(Response.serializer(dataSerializer), from)
|
||||||
}
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
sealed class RequestError
|
||||||
|
|
||||||
|
data class RetryAfterError(
|
||||||
|
val seconds: Long,
|
||||||
|
val startCountingMillis: Long
|
||||||
|
) : RequestError() {
|
||||||
|
val canContinue = TimeUnit.SECONDS.toMillis(seconds) + startCountingMillis
|
||||||
|
val leftToRetry: Long
|
||||||
|
get() = canContinue - System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MigrateChatId(
|
||||||
|
val newChatId: ChatId
|
||||||
|
) : RequestError()
|
||||||
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Deprecated because incorrect name",
|
||||||
|
ReplaceWith("Response")
|
||||||
|
)
|
||||||
|
typealias ResponseParameters<T> = Response<T>
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Response<T : Any>(
|
||||||
|
val ok: Boolean = false,
|
||||||
|
@Optional
|
||||||
|
val description: String? = null,
|
||||||
|
@SerialName("error_code")
|
||||||
|
@Optional
|
||||||
|
val errorCode: Int? = null,
|
||||||
|
@Optional
|
||||||
|
val result: T? = null,
|
||||||
|
@Optional
|
||||||
|
val parameters: ResponseParametersRaw? = null
|
||||||
|
)
|
@ -1,30 +0,0 @@
|
|||||||
package com.github.insanusmokrassar.TelegramBotAPI.types
|
|
||||||
|
|
||||||
import kotlinx.serialization.*
|
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class ResponseParameters<T : Any>(
|
|
||||||
val ok: Boolean = false,
|
|
||||||
@Optional
|
|
||||||
val description: String? = null,
|
|
||||||
@SerialName("migrate_to_chat_id")
|
|
||||||
@Optional
|
|
||||||
val migrateToChatId: Identifier? = null,
|
|
||||||
@SerialName("retry_after")
|
|
||||||
@Optional
|
|
||||||
val retryAfter: Int? = null,
|
|
||||||
@SerialName("error_code")
|
|
||||||
@Optional
|
|
||||||
val errorCode: Int? = null,
|
|
||||||
@Optional
|
|
||||||
val result: T? = null
|
|
||||||
) {
|
|
||||||
@Transient
|
|
||||||
val waitUntil: DateTime? by lazy {
|
|
||||||
retryAfter ?.let {
|
|
||||||
DateTime.now().plus(TimeUnit.SECONDS.toMillis(it.toLong()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ResponseParametersRaw(
|
||||||
|
@SerialName("migrate_to_chat_id")
|
||||||
|
@Optional
|
||||||
|
private val migrateToChatId: ChatId? = null,
|
||||||
|
@SerialName("retry_after")
|
||||||
|
@Optional
|
||||||
|
private val retryAfter: Long? = null
|
||||||
|
) {
|
||||||
|
@Transient
|
||||||
|
private val createTime: Long = System.currentTimeMillis()
|
||||||
|
@Transient
|
||||||
|
val error: RequestError? by lazy {
|
||||||
|
when {
|
||||||
|
migrateToChatId != null -> MigrateChatId(migrateToChatId);
|
||||||
|
retryAfter != null -> RetryAfterError(retryAfter, createTime);
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestException
|
|||||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
|
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.*
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.*
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters
|
import com.github.insanusmokrassar.TelegramBotAPI.types.Response
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
|
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
|
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
|
||||||
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
|
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
|
||||||
@ -147,7 +147,7 @@ fun RequestsExecutor.startGettingOfUpdates(
|
|||||||
|
|
||||||
fun <T: Any> RequestsExecutor.executeAsync(
|
fun <T: Any> RequestsExecutor.executeAsync(
|
||||||
request: Request<T>,
|
request: Request<T>,
|
||||||
onFail: (suspend (ResponseParameters<*>) -> Unit)? = null,
|
onFail: (suspend (Response<*>) -> Unit)? = null,
|
||||||
scope: CoroutineScope = GlobalScope,
|
scope: CoroutineScope = GlobalScope,
|
||||||
onSuccess: (suspend (T) -> Unit)? = null
|
onSuccess: (suspend (T) -> Unit)? = null
|
||||||
): Job {
|
): Job {
|
||||||
|
Loading…
Reference in New Issue
Block a user