Replace "UpdatesFilter" and "UpdatesPoller" into another package

This commit is contained in:
InsanusMokrassar 2019-05-10 11:26:58 +08:00
parent 62c4223648
commit 25dcd9bc52
7 changed files with 244 additions and 179 deletions

View File

@ -20,6 +20,8 @@ some default library
### 0.14.1
* Replace `UpdatesFilter` and `UpdatesPoller` into another package
## 0.13.0 Telegram Polls
* Type `PollOption` and `AnonymousPollOption` added

View File

@ -0,0 +1,106 @@
package com.github.insanusmokrassar.TelegramBotAPI.updateshandlers
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.UpdateReceiver
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.UpdatesFilter
data class UpdatesFilter(
private val messageCallback: UpdateReceiver<MessageUpdate>? = null,
private val messageMediaGroupCallback: UpdateReceiver<MessageMediaGroupUpdate>? = null,
private val editedMessageCallback: UpdateReceiver<EditMessageUpdate>? = null,
private val editedMessageMediaGroupCallback: UpdateReceiver<EditMessageMediaGroupUpdate>? = null,
private val channelPostCallback: UpdateReceiver<ChannelPostUpdate>? = null,
private val channelPostMediaGroupCallback: UpdateReceiver<ChannelPostMediaGroupUpdate>? = null,
private val editedChannelPostCallback: UpdateReceiver<EditChannelPostUpdate>? = null,
private val editedChannelPostMediaGroupCallback: UpdateReceiver<EditChannelPostMediaGroupUpdate>? = null,
private val chosenInlineResultCallback: UpdateReceiver<ChosenInlineResultUpdate>? = null,
private val inlineQueryCallback: UpdateReceiver<InlineQueryUpdate>? = null,
private val callbackQueryCallback: UpdateReceiver<CallbackQueryUpdate>? = null,
private val shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
private val preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null
) {
val asUpdateReceiver: UpdateReceiver<Update> = this::invoke
val allowedUpdates = listOfNotNull(
(messageCallback ?: messageMediaGroupCallback) ?.let { UPDATE_MESSAGE },
(editedMessageCallback ?: editedMessageMediaGroupCallback) ?.let { UPDATE_EDITED_MESSAGE },
(channelPostCallback ?: channelPostMediaGroupCallback) ?.let { UPDATE_CHANNEL_POST },
(editedChannelPostCallback ?: editedChannelPostMediaGroupCallback) ?.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 }
)
suspend fun invoke(update: Update) {
when (update) {
is MessageUpdate -> messageCallback ?.invoke(update)
is MessageMediaGroupUpdate -> messageMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: messageCallback ?.also { receiver ->
update.origins.mapNotNull { it as? MessageUpdate }.forEach {
receiver(it)
}
}
is EditMessageUpdate -> editedMessageCallback ?.invoke(update)
is EditMessageMediaGroupUpdate -> editedMessageMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: editedMessageCallback ?.also { receiver ->
update.origins.mapNotNull { it as? EditMessageUpdate }.forEach {
receiver(it)
}
}
is ChannelPostUpdate -> channelPostCallback ?.invoke(update)
is ChannelPostMediaGroupUpdate -> channelPostMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: channelPostCallback ?.also { receiver ->
update.origins.mapNotNull { it as? ChannelPostUpdate }.forEach {
receiver(it)
}
}
is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(update)
is EditChannelPostMediaGroupUpdate -> editedChannelPostMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: editedChannelPostCallback ?.also { receiver ->
update.origins.mapNotNull { it as? EditChannelPostUpdate }.forEach {
receiver(it)
}
}
is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(update)
is InlineQueryUpdate -> inlineQueryCallback ?.invoke(update)
is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(update)
is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(update)
is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update)
}
}
}
fun createSimpleUpdateFilter(
messageCallback: UpdateReceiver<MessageUpdate>? = null,
mediaGroupCallback: UpdateReceiver<MediaGroupUpdate>? = null,
editedMessageCallback: UpdateReceiver<EditMessageUpdate>? = null,
channelPostCallback: UpdateReceiver<ChannelPostUpdate>? = null,
editedChannelPostCallback: UpdateReceiver<EditChannelPostUpdate>? = null,
chosenInlineResultCallback: UpdateReceiver<ChosenInlineResultUpdate>? = null,
inlineQueryCallback: UpdateReceiver<InlineQueryUpdate>? = null,
callbackQueryCallback: UpdateReceiver<CallbackQueryUpdate>? = null,
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null
): UpdatesFilter = UpdatesFilter(
messageCallback = messageCallback,
messageMediaGroupCallback = mediaGroupCallback,
editedMessageCallback = editedMessageCallback,
editedMessageMediaGroupCallback = mediaGroupCallback,
channelPostCallback = channelPostCallback,
channelPostMediaGroupCallback = mediaGroupCallback,
editedChannelPostCallback = editedChannelPostCallback,
editedChannelPostMediaGroupCallback = mediaGroupCallback,
chosenInlineResultCallback = chosenInlineResultCallback,
inlineQueryCallback = inlineQueryCallback,
callbackQueryCallback = callbackQueryCallback,
shippingQueryCallback = shippingQueryCallback,
preCheckoutQueryCallback = preCheckoutQueryCallback
)

View File

@ -0,0 +1,98 @@
package com.github.insanusmokrassar.TelegramBotAPI.updateshandlers
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.requests.GetUpdates
import com.github.insanusmokrassar.TelegramBotAPI.requests.webhook.DeleteWebhook
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseMessageUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.UpdateReceiver
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.executeUnsafe
import com.github.insanusmokrassar.TelegramBotAPI.utils.mediaGroupId
import com.github.insanusmokrassar.TelegramBotAPI.utils.toMediaGroupUpdate
import kotlinx.coroutines.*
import java.util.concurrent.Executors
class UpdatesPoller(
private val executor: RequestsExecutor,
private val requestsDelayMillis: Long = 1000,
private val scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
private val allowedUpdates: List<String>? = null,
private val block: UpdateReceiver<Update>
) {
private var lastHandledUpdate: UpdateIdentifier = 0L
private val mediaGroup: MutableList<BaseMessageUpdate> = mutableListOf()
private var pollerJob: Job? = null
private suspend fun sendToBlock(data: Update) {
block(data)
lastHandledUpdate = data.updateId
}
private suspend fun pushMediaGroupUpdate(update: BaseMessageUpdate? = null) {
val inputMediaGroupId = (update ?.data as? MediaGroupMessage) ?.mediaGroupId
if (mediaGroup.isNotEmpty() && inputMediaGroupId ?.equals(mediaGroup.mediaGroupId) != true) {
mediaGroup.sortBy { it.updateId }
mediaGroup.toMediaGroupUpdate() ?.let {
sendToBlock(it)
} ?: mediaGroup.forEach {
sendToBlock(it)
}
mediaGroup.clear()
}
inputMediaGroupId ?.let {
mediaGroup.add(update)
} ?: sendToBlock(update ?: return)
}
private suspend fun getUpdates(): List<Update> {
return executor.execute(
GetUpdates(
lastHandledUpdate + 1, // incremented because offset counted from 1 when updates id from 0
allowed_updates = allowedUpdates
)
).map {
it.asUpdate
}
}
private suspend fun handleUpdates(updates: List<Update>) {
for (update in updates) {
(update as? BaseMessageUpdate) ?.let {
if (it.data is MediaGroupMessage) {
pushMediaGroupUpdate(it)
} else {
null
}
} ?:let {
pushMediaGroupUpdate()
sendToBlock(update)
}
}
pushMediaGroupUpdate()
}
suspend fun start(): Job {
executor.executeUnsafe(DeleteWebhook())
return pollerJob ?: scope.launch {
while (isActive) {
delay(requestsDelayMillis)
try {
val updates = getUpdates()
handleUpdates(updates)
} catch (e: Exception) {
e.printStackTrace()
}
}
}.also {
pollerJob = it
}
}
suspend fun stop() {
pollerJob ?.cancelAndJoin()
}
}

View File

@ -1,81 +1,25 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils.extensions
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesFilter
data class UpdatesFilter(
private val messageCallback: UpdateReceiver<MessageUpdate>? = null,
private val messageMediaGroupCallback: UpdateReceiver<MessageMediaGroupUpdate>? = null,
private val editedMessageCallback: UpdateReceiver<EditMessageUpdate>? = null,
private val editedMessageMediaGroupCallback: UpdateReceiver<EditMessageMediaGroupUpdate>? = null,
private val channelPostCallback: UpdateReceiver<ChannelPostUpdate>? = null,
private val channelPostMediaGroupCallback: UpdateReceiver<ChannelPostMediaGroupUpdate>? = null,
private val editedChannelPostCallback: UpdateReceiver<EditChannelPostUpdate>? = null,
private val editedChannelPostMediaGroupCallback: UpdateReceiver<EditChannelPostMediaGroupUpdate>? = null,
private val chosenInlineResultCallback: UpdateReceiver<ChosenInlineResultUpdate>? = null,
private val inlineQueryCallback: UpdateReceiver<InlineQueryUpdate>? = null,
private val callbackQueryCallback: UpdateReceiver<CallbackQueryUpdate>? = null,
private val shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
private val preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null
) {
val asUpdateReceiver: UpdateReceiver<Update> = this::invoke
val allowedUpdates = listOfNotNull(
(messageCallback ?: messageMediaGroupCallback) ?.let { UPDATE_MESSAGE },
(editedMessageCallback ?: editedMessageMediaGroupCallback) ?.let { UPDATE_EDITED_MESSAGE },
(channelPostCallback ?: channelPostMediaGroupCallback) ?.let { UPDATE_CHANNEL_POST },
(editedChannelPostCallback ?: editedChannelPostMediaGroupCallback) ?.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 }
@Deprecated(
"Replaced in separated package",
ReplaceWith(
"UpdatesFilter",
"com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesFilter"
)
)
typealias UpdatesFilter = UpdatesFilter
suspend fun invoke(update: Update) {
when (update) {
is MessageUpdate -> messageCallback ?.invoke(update)
is MessageMediaGroupUpdate -> messageMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: messageCallback ?.also { receiver ->
update.origins.mapNotNull { it as? MessageUpdate }.forEach {
receiver(it)
}
}
is EditMessageUpdate -> editedMessageCallback ?.invoke(update)
is EditMessageMediaGroupUpdate -> editedMessageMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: editedMessageCallback ?.also { receiver ->
update.origins.mapNotNull { it as? EditMessageUpdate }.forEach {
receiver(it)
}
}
is ChannelPostUpdate -> channelPostCallback ?.invoke(update)
is ChannelPostMediaGroupUpdate -> channelPostMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: channelPostCallback ?.also { receiver ->
update.origins.mapNotNull { it as? ChannelPostUpdate }.forEach {
receiver(it)
}
}
is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(update)
is EditChannelPostMediaGroupUpdate -> editedChannelPostMediaGroupCallback ?.also { receiver ->
receiver(update)
} ?: editedChannelPostCallback ?.also { receiver ->
update.origins.mapNotNull { it as? EditChannelPostUpdate }.forEach {
receiver(it)
}
}
is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(update)
is InlineQueryUpdate -> inlineQueryCallback ?.invoke(update)
is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(update)
is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(update)
is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update)
}
}
}
@Deprecated(
"Replaced in separated package",
ReplaceWith(
"createSimpleUpdateFilter",
"com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.createSimpleUpdateFilter"
)
)
fun createSimpleUpdateFilter(
messageCallback: UpdateReceiver<MessageUpdate>? = null,
mediaGroupCallback: UpdateReceiver<MediaGroupUpdate>? = null,
@ -87,18 +31,15 @@ fun createSimpleUpdateFilter(
callbackQueryCallback: UpdateReceiver<CallbackQueryUpdate>? = null,
shippingQueryCallback: UpdateReceiver<ShippingQueryUpdate>? = null,
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null
): UpdatesFilter = UpdatesFilter(
messageCallback = messageCallback,
messageMediaGroupCallback = mediaGroupCallback,
editedMessageCallback = editedMessageCallback,
editedMessageMediaGroupCallback = mediaGroupCallback,
channelPostCallback = channelPostCallback,
channelPostMediaGroupCallback = mediaGroupCallback,
editedChannelPostCallback = editedChannelPostCallback,
editedChannelPostMediaGroupCallback = mediaGroupCallback,
chosenInlineResultCallback = chosenInlineResultCallback,
inlineQueryCallback = inlineQueryCallback,
callbackQueryCallback = callbackQueryCallback,
shippingQueryCallback = shippingQueryCallback,
preCheckoutQueryCallback = preCheckoutQueryCallback
): UpdatesFilter = com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.createSimpleUpdateFilter(
messageCallback,
mediaGroupCallback,
editedMessageCallback,
channelPostCallback,
editedChannelPostCallback,
chosenInlineResultCallback,
inlineQueryCallback,
callbackQueryCallback,
shippingQueryCallback,
preCheckoutQueryCallback
)

View File

@ -1,96 +1,12 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils.extensions
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.requests.GetUpdates
import com.github.insanusmokrassar.TelegramBotAPI.requests.webhook.DeleteWebhook
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseMessageUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.utils.mediaGroupId
import com.github.insanusmokrassar.TelegramBotAPI.utils.toMediaGroupUpdate
import kotlinx.coroutines.*
import java.util.concurrent.Executors
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesPoller
class UpdatesPoller(
private val executor: RequestsExecutor,
private val requestsDelayMillis: Long = 1000,
private val scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
private val allowedUpdates: List<String>? = null,
private val block: UpdateReceiver<Update>
) {
private var lastHandledUpdate: UpdateIdentifier = 0L
private val mediaGroup: MutableList<BaseMessageUpdate> = mutableListOf()
private var pollerJob: Job? = null
private suspend fun sendToBlock(data: Update) {
block(data)
lastHandledUpdate = data.updateId
}
private suspend fun pushMediaGroupUpdate(update: BaseMessageUpdate? = null) {
val inputMediaGroupId = (update ?.data as? MediaGroupMessage) ?.mediaGroupId
if (mediaGroup.isNotEmpty() && inputMediaGroupId ?.equals(mediaGroup.mediaGroupId) != true) {
mediaGroup.sortBy { it.updateId }
mediaGroup.toMediaGroupUpdate() ?.let {
sendToBlock(it)
} ?: mediaGroup.forEach {
sendToBlock(it)
}
mediaGroup.clear()
}
inputMediaGroupId ?.let {
mediaGroup.add(update)
} ?: sendToBlock(update ?: return)
}
private suspend fun getUpdates(): List<Update> {
return executor.execute(
GetUpdates(
lastHandledUpdate + 1, // incremented because offset counted from 1 when updates id from 0
allowed_updates = allowedUpdates
)
).map {
it.asUpdate
}
}
private suspend fun handleUpdates(updates: List<Update>) {
for (update in updates) {
(update as? BaseMessageUpdate) ?.let {
if (it.data is MediaGroupMessage) {
pushMediaGroupUpdate(it)
} else {
null
}
} ?:let {
pushMediaGroupUpdate()
sendToBlock(update)
}
}
pushMediaGroupUpdate()
}
suspend fun start(): Job {
executor.executeUnsafe(DeleteWebhook())
return pollerJob ?: scope.launch {
while (isActive) {
delay(requestsDelayMillis)
try {
val updates = getUpdates()
handleUpdates(updates)
} catch (e: Exception) {
e.printStackTrace()
}
}
}.also {
pollerJob = it
}
}
suspend fun stop() {
pollerJob ?.cancelAndJoin()
}
}
@Deprecated(
"Replaced in separated package",
ReplaceWith(
"UpdatesPoller",
"com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesPoller"
)
)
typealias UpdatesPoller = UpdatesPoller

View File

@ -4,6 +4,8 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesFilter
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesPoller
import kotlinx.coroutines.*
import java.util.concurrent.Executors

View File

@ -8,8 +8,8 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaG
import com.github.insanusmokrassar.TelegramBotAPI.types.update.RawUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseMessageUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesFilter
import com.github.insanusmokrassar.TelegramBotAPI.utils.toMediaGroupUpdate
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.request.receiveText
import io.ktor.response.respond