All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.insanusmokrassar.AutoPostTelegramBot.plugins.publishers.PostPublisher.kt Maven / Gradle / Ivy

Go to download

It is base library for creating smart bot for simple management of channels posts

There is a newer version: 1.7.0
Show newest version
package com.github.insanusmokrassar.AutoPostTelegramBot.plugins.publishers

import com.github.insanusmokrassar.AutoPostTelegramBot.base.database.tables.PostsMessagesTable
import com.github.insanusmokrassar.AutoPostTelegramBot.base.database.tables.PostsTable
import com.github.insanusmokrassar.AutoPostTelegramBot.base.models.FinalConfig
import com.github.insanusmokrassar.AutoPostTelegramBot.base.models.PostMessage
import com.github.insanusmokrassar.AutoPostTelegramBot.base.plugins.PluginManager
import com.github.insanusmokrassar.AutoPostTelegramBot.base.plugins.commonLogger
import com.github.insanusmokrassar.AutoPostTelegramBot.plugins.base.commands.deletePost
import com.github.insanusmokrassar.AutoPostTelegramBot.plugins.choosers.Chooser
import com.github.insanusmokrassar.AutoPostTelegramBot.plugins.forwarders.Forwarder
import com.github.insanusmokrassar.AutoPostTelegramBot.plugins.forwarders.ForwardersPlugin
import com.github.insanusmokrassar.AutoPostTelegramBot.utils.extensions.executeAsync
import com.github.insanusmokrassar.AutoPostTelegramBot.utils.extensions.executeBlocking
import com.pengrad.telegrambot.TelegramBot
import com.pengrad.telegrambot.model.Message
import com.pengrad.telegrambot.request.*
import kotlinx.coroutines.experimental.channels.BroadcastChannel
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.launch
import java.lang.ref.WeakReference

typealias PostIdListPostMessagesTelegramMessages = Pair>
private typealias ChatIdMessageIdPair = Pair

fun makeMapOfExecution(
    messageToPost: List,
    forwardersList: List
): List>> {
    val mapOfExecution = mutableListOf>>()

    var forwarder: Forwarder? = null

    messageToPost.forEach { message ->
        if (forwarder?.canForward(message) != true) {
            val iterator = forwardersList.iterator()
            while (forwarder?.canForward(message) != true) {
                if (!iterator.hasNext()) {
                    return@forEach
                }
                forwarder = iterator.next()
            }
        }
        if (mapOfExecution.lastOrNull()?.first != forwarder) {
            forwarder?.let {
                mapOfExecution.add(
                    it to mutableListOf()
                )
            }
        }
        mapOfExecution.last().second.add(message)
    }

    return mapOfExecution
}

class PostPublisher : Publisher {
    val postPublishedChannel = BroadcastChannel(
        Channel.CONFLATED
    )

    private var botWR: WeakReference? = null

    private var sourceChatId: Long? = null
    private var targetChatId: Long? = null
    private var logsChatId: Long? = null
    private var forwardersList: List = emptyList()

    private var publishPostCommand: PublishPost? = null

    override fun onInit(
        bot: TelegramBot,
        baseConfig: FinalConfig,
        pluginManager: PluginManager
    ) {
        botWR = WeakReference(bot).also {
            publishPostCommand = PublishPost(
                pluginManager.plugins.firstOrNull { it is Chooser } as? Chooser,
                pluginManager.plugins.firstOrNull { it is Publisher } as Publisher,
                it,
                baseConfig.logsChatId
            )
        }

        sourceChatId = baseConfig.sourceChatId
        targetChatId = baseConfig.targetChatId
        logsChatId = baseConfig.logsChatId
        forwardersList = (pluginManager.plugins.firstOrNull {
            it is ForwardersPlugin
        } as? ForwardersPlugin) ?.forwarders ?: emptyList()
    }

    override suspend fun publishPost(postId: Int) {
        val bot = botWR ?.get() ?: return
        val sourceChatId: Long = sourceChatId ?: return
        val targetChatId: Long = targetChatId ?: return
        val logsChatId: Long = logsChatId ?: return

        val messagesToDelete = mutableListOf()

        try {
            bot.executeBlocking(
                SendMessage(
                    logsChatId,
                    "Start post"
                )
            ) ?.message() ?.let {
                messagesToDelete.add(it.chat().id() to it.messageId())
            }

            val messageToPost = PostsMessagesTable.getMessagesOfPost(postId).also {
                if (it.isEmpty()) {
                    PostsTable.removePost(postId)
                    return
                }
                it.forEach {
                    message ->
                    try {
                        bot.executeBlocking(
                            ForwardMessage(
                                logsChatId,
                                sourceChatId,
                                message.messageId
                            ).disableNotification(
                                true
                            )
                        ) ?.message()?.also {
                            messagesToDelete.add(it.chat().id() to it.messageId())
                            message.message = it
                        }
                    } catch (e: Exception) {
                        commonLogger.warning(
                            "Can't forward message with id: ${message.messageId}"
                        )
                    }
                }
            }

            val mapOfExecution = makeMapOfExecution(
                messageToPost,
                forwardersList
            )

            mapOfExecution.map {
                (forwarder, messages) ->
                forwarder.forward(
                    bot,
                    targetChatId,
                    *messages.toTypedArray()
                )
            }.let {
                it.flatMap {
                    it.map {
                        it.value
                    }
                }.forEach {
                    try {
                        bot.executeBlocking(
                            ForwardMessage(
                                logsChatId,
                                it.chat().id(),
                                it.messageId()
                            )
                        )
                    } catch (e: Exception) {
                        commonLogger.warning(
                            "Can't forward message with id: ${it.messageId()}"
                        )
                    }
                }
                val resultMap = mutableMapOf()
                it.forEach {
                    resultMap.putAll(it)
                }
                launch {
                    postPublishedChannel.send(
                        postId to resultMap
                    )
                }
            }

            deletePost(
                bot,
                sourceChatId,
                logsChatId,
                postId
            )
        } catch (e: Throwable) {
            e.printStackTrace()
            commonLogger.throwing(
                name,
                "Trying to publish",
                e
            )
        } finally {
            messagesToDelete.forEach {
                bot.executeAsync(
                    DeleteMessage(
                        it.first,
                        it.second
                    )
                )
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy