TelegramBotTutorial/welcome/src/main/kotlin/WelcomePlugin.kt

211 lines
8.3 KiB
Kotlin
Raw Normal View History

2022-07-09 17:41:37 +00:00
import db.WelcomeTable
import dev.inmo.kslog.common.e
import dev.inmo.kslog.common.logger
import dev.inmo.plagubot.Plugin
2022-07-09 17:41:37 +00:00
import dev.inmo.plagubot.plugins.commands.full
import dev.inmo.tgbotapi.bot.exceptions.RequestException
import dev.inmo.tgbotapi.extensions.api.answers.answer
2022-09-22 10:06:21 +00:00
import dev.inmo.tgbotapi.extensions.api.delete
2022-07-09 17:41:37 +00:00
import dev.inmo.tgbotapi.extensions.api.edit.edit
2022-09-22 08:29:09 +00:00
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.send
2022-07-10 19:33:53 +00:00
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
2023-04-27 06:11:39 +00:00
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitAnyContentMessage
2022-07-09 17:41:37 +00:00
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitMessageDataCallbackQuery
2022-09-22 08:29:09 +00:00
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onNewChatMembers
2022-07-11 07:07:42 +00:00
import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat
import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage
2022-09-22 09:00:40 +00:00
import dev.inmo.tgbotapi.extensions.utils.ifCommonGroupContentMessage
2022-09-22 08:29:09 +00:00
import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton
import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard
2022-09-22 09:00:40 +00:00
import dev.inmo.tgbotapi.libraries.cache.admins.AdminsCacheAPI
2022-07-09 17:41:37 +00:00
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.MilliSeconds
import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.commands.BotCommandScope
import dev.inmo.tgbotapi.types.message.abstracts.CommonGroupContentMessage
import dev.inmo.tgbotapi.types.message.content.MessageContent
2022-09-22 09:13:27 +00:00
import dev.inmo.tgbotapi.utils.*
2022-07-09 17:41:37 +00:00
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.serialization.Serializable
2022-09-22 08:29:09 +00:00
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
2022-07-09 17:41:37 +00:00
import model.ChatSettings
import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.module.Module
2022-07-09 17:41:37 +00:00
import org.koin.core.qualifier.named
/**
* This is template of plugin with preset [log]ger, [Config] and template configurations of [setupDI] and [setupBotPlugin].
* Replace [pluginConfigSectionName] value with your one to customize configuration section name
*/
@Serializable
class WelcomePlugin : Plugin {
/**
* Default logger of [WelcomePlugin] got with [logger]
*/
private val log = logger
/**
* Configuration class for current plugin
*
* See realization of [setupDI] to get know how this class will be deserialized from global config
*
* See realization of [setupBotPlugin] to get know how to get access to this class
2022-07-09 17:41:37 +00:00
*
* @param recheckOfAdmin This parameter will be used before setup of
*/
@Serializable
private class Config(
2022-07-09 19:08:55 +00:00
val recheckOfAdmin: MilliSeconds = 60000L
)
/**
* DI configuration of current plugin. Here we are decoding [Config] and put it into [Module] receiver
*/
override fun Module.setupDI(database: Database, params: JsonObject) {
2022-07-09 17:41:37 +00:00
single { get<Json>().decodeFromJsonElement(Config.serializer(), params[pluginConfigSectionName] ?: return@single Config()) }
single { WelcomeTable(database) }
single(named("welcome")) { BotCommand("welcome", "Use to setup welcome message").full(BotCommandScope.AllChatAdministrators) }
}
private suspend fun BehaviourContext.handleWelcomeCommand(
2022-09-22 09:00:40 +00:00
adminsCacheAPI: AdminsCacheAPI,
2022-07-09 17:41:37 +00:00
welcomeTable: WelcomeTable,
config: Config,
groupMessage: CommonGroupContentMessage<MessageContent>
) {
val user = groupMessage.user
2022-09-22 09:00:40 +00:00
if (adminsCacheAPI.isAdmin(groupMessage.chat.id, user.id)) {
2022-09-22 10:06:21 +00:00
val previousMessage = welcomeTable.get(groupMessage.chat.id)
2022-09-22 08:28:49 +00:00
val sentMessage = send(
2022-07-09 17:41:37 +00:00
user,
2022-07-11 07:07:42 +00:00
replyMarkup = flatInlineKeyboard {
2022-09-22 10:06:21 +00:00
if (previousMessage != null) {
dataButton("Unset", unsetData)
}
2022-07-11 07:07:42 +00:00
dataButton("Cancel", cancelData)
2022-07-09 17:41:37 +00:00
}
2022-09-22 08:28:49 +00:00
) {
regular("Ok, send me the message which should be used as welcome message for chat ")
underline(groupMessage.chat.title)
}
2022-07-09 17:41:37 +00:00
oneOf(
2022-07-10 19:33:53 +00:00
parallel {
2022-07-09 17:41:37 +00:00
val query = waitMessageDataCallbackQuery().filter {
2022-07-11 07:07:42 +00:00
it.data == unsetData && it.message.sameMessage(sentMessage)
2022-07-09 17:41:37 +00:00
}.first()
2022-09-22 08:28:49 +00:00
edit(sentMessage) {
2022-07-10 19:33:53 +00:00
if (welcomeTable.unset(groupMessage.chat.id)) {
regular("Welcome message has been removed for chat ")
underline(groupMessage.chat.title)
} else {
regular("Something went wrong on welcome message unsetting for chat ")
underline(groupMessage.chat.title)
}
2022-07-09 17:41:37 +00:00
}
answer(query)
},
2022-07-10 19:33:53 +00:00
parallel {
2022-07-09 17:41:37 +00:00
val query = waitMessageDataCallbackQuery().filter {
2022-07-11 07:07:42 +00:00
it.data == cancelData && it.message.sameMessage(sentMessage)
2022-07-09 17:41:37 +00:00
}.first()
2022-09-22 10:06:21 +00:00
edit(sentMessage) {
2022-09-22 08:28:49 +00:00
regular("You have cancelled change of welcome message for chat ")
underline(groupMessage.chat.title)
}
2022-07-09 17:41:37 +00:00
answer(query)
},
2022-07-10 19:33:53 +00:00
parallel {
2023-04-27 06:11:39 +00:00
val message = waitAnyContentMessage().filter {
2022-07-11 07:07:42 +00:00
it.sameChat(sentMessage)
2022-07-09 17:41:37 +00:00
}.first()
val success = welcomeTable.set(
ChatSettings(
groupMessage.chat.id,
message.chat.id,
message.messageId
)
)
2022-09-22 08:28:49 +00:00
reply(message) {
2022-07-10 19:33:53 +00:00
if (success) {
regular("Welcome message has been changed for chat ")
underline(groupMessage.chat.title)
regular(".\n\n")
bold("Please, do not delete this message if you want it to work and don't stop this bot to keep welcome message works right")
} else {
regular("Something went wrong on welcome message changing for chat ")
underline(groupMessage.chat.title)
}
2022-07-09 17:41:37 +00:00
}
2022-09-22 10:06:21 +00:00
delete(sentMessage)
2022-07-09 17:41:37 +00:00
},
2022-07-10 19:33:53 +00:00
parallel {
2022-07-09 17:41:37 +00:00
while (isActive) {
delay(config.recheckOfAdmin)
2022-09-22 09:00:40 +00:00
if (adminsCacheAPI.isAdmin(groupMessage.chat.id, user.id)) {
edit(sentMessage, "Sorry, but you are not admin in chat ${groupMessage.chat.title} anymore")
2022-07-09 17:41:37 +00:00
break
}
}
}
)
}
}
/**
* Final configuration of bot. Here we are getting [Config] from [koin]
*/
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
2022-07-09 17:41:37 +00:00
val config = koin.get<Config>()
val welcomeTable = koin.get<WelcomeTable>()
2022-09-22 09:00:40 +00:00
val adminsCacheAPI = koin.get<AdminsCacheAPI>()
2022-07-09 17:41:37 +00:00
onCommand(
"welcome",
2022-07-10 18:48:45 +00:00
initialFilter = { it.chat is GroupChat }
2022-07-09 17:41:37 +00:00
) {
2022-09-22 09:00:40 +00:00
it.ifCommonGroupContentMessage { groupMessage ->
2022-07-09 17:41:37 +00:00
launch {
2022-09-22 09:00:40 +00:00
handleWelcomeCommand(adminsCacheAPI, welcomeTable, config, groupMessage)
2022-07-09 17:41:37 +00:00
}
}
}
onNewChatMembers {
val chatSettings = welcomeTable.get(it.chat.id)
if (chatSettings == null) {
return@onNewChatMembers
}
reply(
it,
chatSettings.sourceChatId,
chatSettings.sourceMessageId
)
2022-07-09 17:41:37 +00:00
}
}
companion object {
private const val pluginConfigSectionName = "welcome"
2022-07-10 18:48:45 +00:00
private const val cancelData = "cancel"
private const val unsetData = "unset"
}
}