From 710b0c4353b3dfd158488713acfbbc3d99bcbd20 Mon Sep 17 00:00:00 2001 From: Artem Darius Weber Date: Thu, 2 Jan 2025 22:29:16 +0300 Subject: [PATCH] init --- .idea/.gitignore | 8 + .idea/inspectionProfiles/Project_Default.xml | 187 ++++++++++++++++++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 14 ++ .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/vk-bot.iml | 8 + Dockerfile | 9 + compose.yaml | 8 + requirements.txt | 3 + src/main.py | 67 +++++++ 11 files changed, 324 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/vk-bot.iml create mode 100644 Dockerfile create mode 100644 compose.yaml create mode 100644 requirements.txt create mode 100644 src/main.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..c83e0bf --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,187 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..c350e97 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5b68a0d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vk-bot.iml b/.idea/vk-bot.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/vk-bot.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..db29e59 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.9-slim + +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY src/ /app/src/ + +CMD ["python", "/app/src/main.py"] \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..7b9a946 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,8 @@ +version: '3.8' +services: + vk_bot: + build: . + environment: + GROUP_ID: "group_id" + ACCESS_TOKEN: "access_token" + restart: unless-stopped \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1a0e494 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +vk_api +transformers +torch \ No newline at end of file diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..cd3a07a --- /dev/null +++ b/src/main.py @@ -0,0 +1,67 @@ +import logging +import vk_api +from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType +import time +from transformers import AutoTokenizer, AutoModelForSequenceClassification +import torch + +# Настройка логирования +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logger = logging.getLogger(__name__) + +model_path = "RUSpam/spam_deberta_v4" +tokenizer = AutoTokenizer.from_pretrained(model_path) +model = AutoModelForSequenceClassification.from_pretrained(model_path) +GROUP_ID = "" +ACCESS_TOKEN = "" +THRESHOLD_REACTIONS = 3 + +def is_spam(message): + inputs = tokenizer(message, return_tensors="pt", truncation=True, max_length=256) + with torch.no_grad(): + outputs = model(**inputs) + logits = outputs.logits + predicted_class = torch.argmax(logits, dim=1).item() + return predicted_class == 1 + +# Основной класс бота +class VkBot: + def __init__(self, group_id, token): + self.group_id = group_id + self.vk_session = vk_api.VkApi(token=token) + self.vk = self.vk_session.get_api() + self.longpoll = VkBotLongPoll(self.vk_session, group_id) + self.message_reactions = {} + + def run(self): + logger.info("Бот запущен!") + for event in self.longpoll.listen(): + if event.type == VkBotEventType.MESSAGE_NEW: + message = event.object['message'] + user_id = message["from_id"] + peer_id = message["peer_id"] + message_id = message["conversation_message_id"] + text = message["text"] + + if peer_id > 2_000_000_000 and is_spam(text): + logger.warning(f"Обнаружено спам-сообщение от пользователя {user_id}: {text}") + self.delete_message(peer_id=peer_id, user_id=user_id, message_id=message_id) + + def delete_message(self, peer_id, user_id, message_id): + """Удалить сообщение""" + if not self.is_conservation_admin(peer_id=peer_id, user_id=user_id): + self.vk.messages.delete(cmids=message_id, peer_id=peer_id) + logger.info(f"Сообщение {message_id} удалено из беседы {peer_id} пользователем {user_id}.") + + def is_conservation_admin(self, peer_id, user_id): + """Проверка пользователя на администратора беседы.""" + members = self.vk.messages.getConversationMembers(peer_id=peer_id) + for member in members['items']: + if member['member_id'] == user_id: + return member['is_admin'] + return False + +# Запуск бота +if __name__ == "__main__": + bot = VkBot(GROUP_ID, ACCESS_TOKEN) + bot.run() \ No newline at end of file