1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-09-10 10:46:20 +00:00
This commit is contained in:
2018-12-26 16:07:24 +08:00
parent 120db4c445
commit 89eda29965
330 changed files with 6934 additions and 3 deletions

View File

@@ -0,0 +1,47 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@ImplicitReflectionSerializer
inline fun <reified T: Any> T.toJsonWithoutNulls(): JsonObject = toJson(serializerByValue(this)).withoutNulls()
inline fun <reified T: Any> T.toJsonWithoutNulls(serializer: KSerializer<T>): JsonObject = toJson(serializer).withoutNulls()
inline fun <reified T: Any> T.toJson(serializer: KSerializer<T>): JsonObject = JsonTreeMapper().writeTree(
this,
serializer
).jsonObject
fun JsonArray.withoutNulls(): JsonArray {
return jsonArray {
forEach {
when (it) {
is JsonObject -> +it.withoutNulls()
is JsonArray -> +it.withoutNulls()
is JsonPrimitive -> +it
}
}
}
}
fun JsonObject.withoutNulls(): JsonObject {
return json {
forEach { (k, v) ->
when (v) {
is JsonObject -> k to v.withoutNulls()
is JsonArray -> k to v.withoutNulls()
!is JsonNull -> k to v
}
}
}
}
fun JsonObject.mapWithCommonValues(): Map<String, Any> = map {
(key, value) ->
key to when (value) {
is JsonPrimitive -> value.contentOrNull ?: value.booleanOrNull ?: value.doubleOrNull ?: value.floatOrNull ?: value.intOrNull
is JsonArray, is JsonObject -> value.toString()
is JsonNull -> null
}
}.toMap().mapNotNullValues()

View File

@@ -0,0 +1,18 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils
fun <K, V> mapOfNotNull(vararg pairs: Pair<K, V?>): Map<K, V> {
return HashMap<K, V>().apply {
pairs.forEach {
(key, value) ->
value ?.also {
put(key, it)
}
}
}
}
fun <K, V> Map<K, V?>.mapNotNullValues(): Map<K, V> = asSequence().mapNotNull {
it.value ?.let { value ->
it.key to value
}
}.toMap()

View File

@@ -0,0 +1,32 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.Matrix
fun <T> row(block: RowBuilder<T>.() -> Unit): List<T> {
return RowBuilder<T>().also(block).row
}
fun <T> MatrixBuilder<T>.row(block: RowBuilder<T>.() -> Unit) {
add(RowBuilder<T>().also(block).row)
}
fun <T> matrix(block: MatrixBuilder<T>.() -> Unit): Matrix<T> {
return MatrixBuilder<T>().also(block).matrix
}
class RowBuilder<T> {
private val mutRow: MutableList<T> = ArrayList()
val row: List<T>
get() = mutRow
fun add(t: T) = mutRow.add(t)
}
class MatrixBuilder<T> {
private val mutMatrix: MutableList<List<T>> = ArrayList()
val matrix: Matrix<T>
get() = mutMatrix
fun add(t: List<T>) = mutMatrix.add(t)
operator fun plus(t: List<T>) = add(t)
}

View File

@@ -0,0 +1,131 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils.extensions
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestException
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.types.CallbackQuery.CallbackQuery
import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts.ChosenInlineResult
import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts.InlineQuery
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.PreCheckoutQuery
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.ShippingQuery
import com.github.insanusmokrassar.TelegramBotAPI.requests.*
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import kotlinx.coroutines.*
typealias UpdateReceiver<T> = suspend Update<T>.() -> Unit
fun RequestsExecutor.startGettingOfUpdates(
requestsDelayMillis: Long = 1000,
scope: CoroutineScope = GlobalScope,
allowedUpdates: List<String>? = null,
block: UpdateReceiver<*>
): Job {
return scope.launch {
var lastHandledUpdate: UpdateIdentifier = 0L
while (isActive) {
delay(requestsDelayMillis)
try {
val updates = execute(
GetUpdates(
lastHandledUpdate + 1,
allowed_updates = allowedUpdates
)
)
for (rawUpdate in updates) {
try {
val update = rawUpdate.asUpdate
block(update)
lastHandledUpdate = update.updateId
} catch (e: Exception) {
// TODO:: add exception handling
e.printStackTrace()
break
}
}
} catch (e: Exception) {
// TODO:: add exception handling
e.printStackTrace()
}
}
}
}
fun RequestsExecutor.startGettingOfUpdates(
messageCallback: UpdateReceiver<Message>? = null,
editedMessageCallback: UpdateReceiver<Message>? = null,
channelPostCallback: UpdateReceiver<Message>? = null,
editedChannelPostCallback: UpdateReceiver<Message>? = null,
chosenInlineResultCallback: UpdateReceiver<ChosenInlineResult>? = null,
inlineQueryCallback: UpdateReceiver<InlineQuery>? = null,
callbackQueryCallback: UpdateReceiver<CallbackQuery>? = null,
shippingQueryCallback: UpdateReceiver<ShippingQuery>? = null,
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQuery>? = null,
requestsDelayMillis: Long = 1000,
scope: CoroutineScope = GlobalScope
): Job {
return startGettingOfUpdates(
requestsDelayMillis,
scope,
listOfNotNull(
messageCallback ?.let { UPDATE_MESSAGE },
editedMessageCallback ?.let { UPDATE_EDITED_MESSAGE },
channelPostCallback ?.let { UPDATE_CHANNEL_POST },
editedChannelPostCallback ?.let { UPDATE_EDITED_CHANNEL_POST },
chosenInlineResultCallback ?.let { UPDATE_CHOSEN_INLINE_RESULT },
inlineQueryCallback ?.let { UPDATE_INLINE_QUERY },
callbackQueryCallback ?.let { UPDATE_CALLBACK_QUERY },
shippingQueryCallback ?.let { UPDATE_SHIPPING_QUERY },
preCheckoutQueryCallback ?.let { UPDATE_PRE_CHECKOUT_QUERY }
)
) {
when (this) {
is MessageUpdate -> messageCallback ?.invoke(this)
is EditMessageUpdate -> editedMessageCallback ?.invoke(this)
is ChannelPostUpdate -> channelPostCallback ?.invoke(this)
is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(this)
is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(this)
is InlineQueryUpdate -> inlineQueryCallback ?.invoke(this)
is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(this)
is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(this)
is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(this)
}
}
}
fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
onFail: (suspend (ResponseParameters<*>) -> Unit)? = null,
scope: CoroutineScope = GlobalScope,
onSuccess: (suspend (T) -> Unit)? = null
): Job {
return scope.launch {
try {
val result = execute(request)
onSuccess ?.invoke(result)
} catch (e: RequestException) {
onFail ?.invoke(e.response)
}
}
}
fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
scope: CoroutineScope = GlobalScope
): Job {
return scope.async { execute(request) }
}
suspend fun <T: Any> RequestsExecutor.executeUnsafe(
request: Request<T>
): T? {
return try {
execute(request)
} catch (e: RequestException) {
null
}
}