Skip to content

Commit

Permalink
feat: реализация блокировки по триггеру в сообщении
Browse files Browse the repository at this point in the history
  • Loading branch information
PatakIN13 committed Jan 20, 2025
1 parent 5fcf514 commit d8888bd
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 0 deletions.
146 changes: 146 additions & 0 deletions src/main/kotlin/com/github/djaler/evilbot/handlers/SpamHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.github.djaler.evilbot.handlers

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.github.djaler.evilbot.handlers.base.CallbackQueryHandler
import com.github.djaler.evilbot.handlers.base.CommonMessageHandler
import com.github.djaler.evilbot.service.ChatService
import com.github.djaler.evilbot.service.UserService
import com.github.djaler.evilbot.utils.createCallbackDataForHandler
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.extensions.api.answers.answerCallbackQuery
import dev.inmo.tgbotapi.extensions.api.chat.members.banChatMember
import dev.inmo.tgbotapi.extensions.api.deleteMessage
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.utils.asFromUserMessage
import dev.inmo.tgbotapi.extensions.utils.asPossiblyReplyMessage
import dev.inmo.tgbotapi.extensions.utils.asPublicChat
import dev.inmo.tgbotapi.extensions.utils.asTextContent
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackDataInlineKeyboardButton
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.queries.callback.MessageDataCallbackQuery
import dev.inmo.tgbotapi.utils.PreviewFeature
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
import org.springframework.stereotype.Component
import javax.annotation.PostConstruct


@Component
class SpamHandler(
private val objectMapper: ObjectMapper,
private val chatService: ChatService,
private val userService: UserService,
private val requestsExecutor: RequestsExecutor
) : CommonMessageHandler() {

private lateinit var triggers: List<String>

override val order = Int.MIN_VALUE

@PostConstruct
fun init() {
val resources = PathMatchingResourcePatternResolver().getResources("classpath:spam_trigger.json")

triggers = resources.flatMap { resource ->
val reactions: List<String> = objectMapper.readValue(resource.inputStream)
reactions
}
}

@OptIn(PreviewFeature::class)
override suspend fun handleMessage(message: CommonMessage<*>): Boolean {
val content = message.content.asTextContent() ?: return false

if (triggers.none { Regex(it, RegexOption.IGNORE_CASE).containsMatchIn(content.text) }
){
return false
}

val chat = message.chat.asPublicChat() ?: return false
val user = message.asFromUserMessage()?.user ?: return false

val (chatEntity, _) = chatService.getOrCreateChatFrom(chat)
val (userEntity, _) = userService.getOrCreateUserFrom(user)

val statistic = userService.getStatistic(userEntity, chatEntity)
val buttonLabels = listOf("Пощадить", "Нет пощады")

if (statistic == null || statistic.messagesCount < 1000) {
val buttons = buttonLabels.map { label ->
CallbackDataInlineKeyboardButton(
label,
createCallbackDataForHandler(
SpamCallbackData(user.id, label).encode(),
SpamCallbackHandler::class.java
)
)
}

requestsExecutor.reply(
message,
"Ты похож на скамера, что делать?",
replyMarkup = InlineKeyboardMarkup(listOf(buttons))
)

return true
}
return false
}
}

@Component
class SpamCallbackHandler(
private val requestsExecutor: RequestsExecutor
) : CallbackQueryHandler() {
@OptIn(PreviewFeature::class)
override suspend fun handleCallback(query: MessageDataCallbackQuery, data: String) {
val chat = query.message.chat
val callbackData = SpamCallbackData.decode(data)

if (query.user.id == callbackData.userId) {
requestsExecutor.answerCallbackQuery(query, "А тебя не спрашивали")
return
}

if (callbackData.buttonText == "Пощадить") {
requestsExecutor.answerCallbackQuery(query, "Ну ладно")
query.message.asPossiblyReplyMessage()?.replyTo?.let {
requestsExecutor.reply(it, "Сомнительно, но окей")
}
} else {
requestsExecutor.answerCallbackQuery(query, "Никакой пощады для скамеров")
try {
requestsExecutor.banChatMember(chat.id, callbackData.userId)
query.message.asPossiblyReplyMessage()?.replyTo?.let {
requestsExecutor.deleteMessage(chat.id, it.messageId)
}
} catch (e: Exception) {
query.message.asPossiblyReplyMessage()?.replyTo?.let {
requestsExecutor.reply(it, "Этот скамер слишком хорош, чтобы быть забаненным")
}
}
}
requestsExecutor.deleteMessage(chat.id, query.message.messageId)
}
}

data class SpamCallbackData(
val userId: UserId,
val buttonText: String
) {
companion object {
fun decode(data: String): SpamCallbackData {
val parts = data.split(":")
return SpamCallbackData(
UserId(parts[0].toLong()),
parts[1]
)
}
}

fun encode(): String {
return "${userId.chatId}:${buttonText}"
}
}
8 changes: 8 additions & 0 deletions src/main/resources/spam_trigger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
"\\bзаработок на крипте\\b",
"\\bзаработок на криптовалюте\\b",
"\\bдостойный доход\\b",
"\\bгибкий график\\b",
"\\bудаленная работа\\b",
"\\bпредлагаем сотрудничество\\b"
]

0 comments on commit d8888bd

Please sign in to comment.