Код с добавленной бд

parent 62e64e71
import asyncio import asyncio
from aiogram import Bot, Dispatcher, Router from aiogram import Bot, Dispatcher, Router
from aiogram.types import ChatMemberUpdated, Message, BotCommand from aiogram.types import ChatMemberUpdated, Message
from aiogram.exceptions import AiogramError from aiogram.exceptions import AiogramError
from itertools import chain from itertools import chain
import os import os
...@@ -8,10 +8,13 @@ from dotenv import load_dotenv ...@@ -8,10 +8,13 @@ from dotenv import load_dotenv
from aiogram.filters import Command from aiogram.filters import Command
import logging import logging
from aiogram import types from aiogram import types
from aiogram.types import ChatMemberUpdated, Message, BotCommand
from spam_keywords import is_spam, SPAM_KEYWORDS from spam_keywords import is_spam, SPAM_KEYWORDS
from symbol_utils import has_mixed_layout, is_arabic_name, normalize_text_to_infinitive from symbol_utils import has_mixed_layout, is_arabic_name, normalize_text_to_infinitive
from sqlite_tools import create_db, add_user, user_exists, ban_user, is_user_banned
import sqlite3
# Загрузка переменных из файла .env # Загрузка переменных из файла .env
load_dotenv() load_dotenv()
...@@ -21,6 +24,9 @@ bot_token = os.getenv("BOT_TOKEN") ...@@ -21,6 +24,9 @@ bot_token = os.getenv("BOT_TOKEN")
log_chat_id = os.getenv("LOG_CHAT_ID") log_chat_id = os.getenv("LOG_CHAT_ID")
main_chat_id = os.getenv("MAIN_CHAT_ID") main_chat_id = os.getenv("MAIN_CHAT_ID")
# Вызов функции для создания базы данных или подключения к существующей
create_db()
# Инициализация бота и диспетчера # Инициализация бота и диспетчера
bot = Bot(token=bot_token) bot = Bot(token=bot_token)
dp = Dispatcher() dp = Dispatcher()
...@@ -84,7 +90,7 @@ tg_log_handler.setLevel(log_level) ...@@ -84,7 +90,7 @@ tg_log_handler.setLevel(log_level)
tg_log_handler.setFormatter(formatter) tg_log_handler.setFormatter(formatter)
# Добавляем обработчик в логгер # Добавляем обработчик в логгер
logger.addHandler(tg_log_handler) logger.addHandler(tg_log_handler)
@router.chat_member() @router.chat_member()
async def welcome_new_user(event: ChatMemberUpdated): async def welcome_new_user(event: ChatMemberUpdated):
...@@ -93,6 +99,24 @@ async def welcome_new_user(event: ChatMemberUpdated): ...@@ -93,6 +99,24 @@ async def welcome_new_user(event: ChatMemberUpdated):
if event.new_chat_member.status == "member" and event.old_chat_member.status not in ["member", "administrator", "creator"]: if event.new_chat_member.status == "member" and event.old_chat_member.status not in ["member", "administrator", "creator"]:
new_user = event.new_chat_member.user new_user = event.new_chat_member.user
# Проверка, если пользователь находится в таблице забаненных
if is_user_banned(new_user.id):
try:
# Если пользователь в списке забаненных, баним его в чате
await bot.ban_chat_member(event.chat.id, new_user.id)
logger.info(f"User {new_user.first_name} ({new_user.id}) is banned immediately after joining, due to being in banned_users table.", extra={"chat_id": event.chat.id})
except AiogramError as e:
logger.error(f"Failed to ban user {new_user.id}. Error: {e}", extra={"chat_id": event.chat.id})
except Exception as e:
logger.error(f"Error banning user {new_user.id}: {e}", extra={"chat_id": event.chat.id})
return # Прерываем дальнейшую обработку, чтобы не добавлять забаненного пользователя в активные
# Добавляем пользователя в базу данных
if not user_exists(new_user.id):
add_user(new_user.id, new_user.first_name, new_user.last_name, new_user.username)
logger.info(f"User {new_user.first_name} ({new_user.id}) added to active users.", extra={"chat_id": event.chat.id})
# Проверка, если имя пользователя содержит арабские символы # Проверка, если имя пользователя содержит арабские символы
if is_arabic_name(new_user.first_name): if is_arabic_name(new_user.first_name):
try: try:
...@@ -106,12 +130,13 @@ async def welcome_new_user(event: ChatMemberUpdated): ...@@ -106,12 +130,13 @@ async def welcome_new_user(event: ChatMemberUpdated):
except Exception as e: except Exception as e:
logger.error(f"Error banning user {new_user.id}: {e}", extra={"chat_id": event.chat.id}) logger.error(f"Error banning user {new_user.id}: {e}", extra={"chat_id": event.chat.id})
return return
else: logger.info(f"User {new_user.first_name} ({new_user.id}) added to active users.", extra={"chat_id": event.chat.id}) #else: logger.info(f"User {new_user.first_name} ({new_user.id}) added to active users.", extra={"chat_id": event.chat.id})
@router.message() @router.message()
async def handle_message(message: Message): async def handle_message(message: Message):
"""Обработчик сообщений от пользователей для проверки ответа.""" """Обработчик сообщений от пользователей для проверки ответа."""
chat_id = message.chat.id # Получаем ID чата chat_id = message.chat.id # Получаем ID чата
user_id = message.from_user.id
# Получаем статус пользователя в чате (администратор, участник и т.д.) # Получаем статус пользователя в чате (администратор, участник и т.д.)
try: try:
chat_member = await bot.get_chat_member(message.chat.id, message.from_user.id) chat_member = await bot.get_chat_member(message.chat.id, message.from_user.id)
...@@ -130,51 +155,122 @@ async def handle_message(message: Message): ...@@ -130,51 +155,122 @@ async def handle_message(message: Message):
text = message.text or message.caption or "" text = message.text or message.caption or ""
text = " ".join(normalize_text_to_infinitive(text, chat_id)) # Убедимся, что это строка text = " ".join(normalize_text_to_infinitive(text, chat_id)) # Убедимся, что это строка
# Проверка на смешанную раскладку # Проверяем, если это первое сообщение пользователя
if text and has_mixed_layout(text, chat_id): conn = sqlite3.connect('users.db')
try: cursor = conn.cursor()
await message.delete()
logger.debug(f"Message with a mixed layout successfully deleted from group.", extra={"chat_id": chat_id}) cursor.execute('SELECT messages_checked FROM users WHERE id = ?', (user_id,))
return user = cursor.fetchone()
except Exception as e:
logger.error(f"Error deleting a message with a mixed layout. Error: {e}", extra={"chat_id": chat_id})
# Проверка на мультимедиа (фото/видео) и его подпись if user:
if (message.photo or message.video or message.document) and text.strip() and is_spam(text, chat_id): messages_checked = user[0]
try:
await message.delete()
logger.info(f"Multimedia message with ID {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id})
return
except Exception as e:
logger.error(f"Error deleting a multimedia message. Error: {e}", extra={"chat_id": chat_id})
# Проверка на кнопки/ссылки # Если это не первое сообщение, просто увеличиваем счетчик
if message.reply_markup and hasattr(message.reply_markup, 'inline_keyboard'): if messages_checked < 5:
for button in chain(*message.reply_markup.inline_keyboard): cursor.execute('UPDATE users SET messages_checked = ? WHERE id = ?', (messages_checked + 1, user_id))
if button.url and any(spam_word in button.url.lower() for spam_word in SPAM_KEYWORDS): conn.commit()
# Проверка на смешанную раскладку
if text and has_mixed_layout(text, chat_id):
try: try:
await message.delete() await message.delete()
logger.info(f"Message with links/buttons with ID {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id}) logger.debug(f"Message with a mixed layout successfully deleted from group.", extra={"chat_id": chat_id})
return
# Баним пользователя в чате и перемещаем в таблицу забаненных
user_id = message.from_user.id
ban_user(user_id, message.from_user.first_name, message.from_user.last_name, message.from_user.username, "Mixed layout detected")
await bot.ban_chat_member(chat_id, user_id)
logger.info(f"User {user_id} has been banned in the chat and moved to banned_users table due to mixed layout.", extra={"chat_id": chat_id})
return
except Exception as e:
logger.error(f"Error deleting a message with a mixed layout. Error: {e}", extra={"chat_id": chat_id})
# Проверка на мультимедиа (фото/видео) и его подпись
if (message.photo or message.video or message.document) and text.strip() and is_spam(text, chat_id):
try:
await message.delete()
logger.info(f"Multimedia message with ID {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id})
# Баним пользователя в чате и перемещаем в таблицу забаненных
user_id = message.from_user.id
ban_user(user_id, message.from_user.first_name, message.from_user.last_name, message.from_user.username, "Spam in multimedia message")
await bot.ban_chat_member(chat_id, user_id)
logger.info(f"User {user_id} has been banned in the chat and moved to banned_users table due to spam in multimedia message.", extra={"chat_id": chat_id})
return
except Exception as e: except Exception as e:
logger.error(f"Error when deleting a message with a button. Error: {e}", extra={"chat_id": chat_id}) logger.error(f"Error deleting a multimedia message. Error: {e}", extra={"chat_id": chat_id})
# Проверка текста на кнопке
if button.text and any(spam_word in button.text.lower() for spam_word in SPAM_KEYWORDS): # Проверка на кнопки/ссылки
if message.reply_markup and hasattr(message.reply_markup, 'inline_keyboard'):
for button in chain(*message.reply_markup.inline_keyboard):
if button.url and any(spam_word in button.url.lower() for spam_word in SPAM_KEYWORDS):
try:
# Удаляем сообщение с кнопкой
await message.delete()
logger.info(f"Message with links/buttons with ID {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id})
# Баним пользователя
user_id = message.from_user.id
ban_user(user_id, message.from_user.first_name, message.from_user.last_name, message.from_user.username, "Spam link/button detected")
# Баним пользователя в чате
await bot.ban_chat_member(chat_id, user_id)
logger.info(f"User {user_id} has been banned in the chat and moved to banned_users table due to spam link/button.", extra={"chat_id": chat_id})
return
except Exception as e:
logger.error(f"Error when deleting a message with a button. Error: {e}", extra={"chat_id": chat_id})
# Проверка текста на кнопке
if button.text and any(spam_word in button.text.lower() for spam_word in SPAM_KEYWORDS):
try:
# Удаляем сообщение с кнопкой
await message.delete()
logger.info(f"Message with spam button text ID {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id})
# Баним пользователя
user_id = message.from_user.id
ban_user(user_id, message.from_user.first_name, message.from_user.last_name, message.from_user.username, "Spam button text detected")
# Баним пользователя в чате
await bot.ban_chat_member(chat_id, user_id)
logger.info(f"User {user_id} has been banned in the chat and moved to banned_users table due to spam button text.", extra={"chat_id": chat_id})
return
except Exception as e:
logger.error(f"Error when deleting a message with a button text. Error: {e}", extra={"chat_id": chat_id})
# Проверка на спам
if is_spam(text, chat_id):
logger.info(f"User {user_id} sent spam: {text}", extra={"chat_id": chat_id})
try: try:
# Удаляем сообщение
await message.delete() await message.delete()
logger.info(f"Message with spam button text ID {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id}) logger.info(f"Message with spam {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id})
return
# Добавляем пользователя в таблицу забаненных и удаляем из таблицы новых участников
ban_user(user_id, message.from_user.first_name, message.from_user.last_name, message.from_user.username, "Spam detected")
logger.info(f"User {user_id} has been banned and moved to banned_users table.", extra={"chat_id": chat_id})
# Бан пользователя в чате
await bot.ban_chat_member(chat_id, user_id)
logger.info(f"User {user_id} has been banned from the chat.", extra={"chat_id": chat_id})
except Exception as e: except Exception as e:
logger.error(f"Error when deleting a message with a button text. Error: {e}", extra={"chat_id": chat_id}) logger.error(f"Error when banning user {user_id}. Error: {e}", extra={"chat_id": chat_id})
else:
# Если сообщений больше не проверяются (т.е. уже 5 сообщений без спама)
cursor.execute('DELETE FROM users WHERE id = ?', (user_id,))
conn.commit()
logger.info(f"User {user_id} removed from the check list after sending 5 messages without spam.", extra={"chat_id": chat_id})
# Проверка на спам conn.close()
if is_spam(text, chat_id):
try:
await message.delete()
logger.info(f"Message wiht spam {message.message_id} successfully deleted from group.", extra={"chat_id": chat_id})
return
except Exception as e:
logger.error(f"Error when trying to delete spam messages. Error: {e}", extra={"chat_id": chat_id})
...@@ -210,11 +306,12 @@ async def report_spam(message: types.Message): ...@@ -210,11 +306,12 @@ async def report_spam(message: types.Message):
async def main(): async def main():
"""Запуск бота.""" """Запуск бота."""
logger.info("bot is running") logger.info("bot is running")
await bot.set_my_commands([ await bot.set_my_commands([
BotCommand(command="/spam", description="Оповестить о спаме уполномоченных людей"), BotCommand(command="/spam", description="Оповестить о спаме уполномоченных людей"),
]) ])
await dp.start_polling(bot) await dp.start_polling(bot)
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) create_db() # Создание базы данных и таблиц
asyncio.run(main())
\ No newline at end of file
...@@ -22,7 +22,9 @@ SPAM_KEYWORDS = [ ...@@ -22,7 +22,9 @@ SPAM_KEYWORDS = [
"спецпредложение","эксклюзивный предложение","мой тг канал", "уникальное предложение", "только сегодня", "лютая жиза", "мерч", "продукция", "коллекция", "спецпредложение","эксклюзивный предложение","мой тг канал", "уникальное предложение", "только сегодня", "лютая жиза", "мерч", "продукция", "коллекция",
# Работа # Работа
"удалённая работа", "человек команда", "удаленный деятельность", "удаленно", "гибкий график", "дистанционный деятельность", "третуется человек", "искать человек", "достойный доход", "удалённая работа", "бакс", "доллар", "нужен человек", "нужен помощник", "вакансии", "удалёнка", "удаленка","условия труда", "писать лс", "личка", "писать в лс", "личное сообщение", "лс", "партнер", "сотрудничество", "прибыль", "бабки", "пасивный заработок","без вложений", "подробности лс", "удалённая работа", "человек команда", "удаленный деятельность", "удаленно", "гибкий график", "дистанционный деятельность", "третуется человек", "искать человек",
"достойный доход", "удалённая работа", "бакс", "доллар", "нужен человек", "нужен помощник", "вакансии", "удалёнка", "удаленка","условия труда", "писать лс", "личка",
"писать в лс", "личное сообщение", "лс", "л.с.", "подробный лс", "подробный л.с.", "партнер", "сотрудничество", "прибыль", "бабки", "пасивный заработок","без вложений", "подробности лс",
# Мошенничество # Мошенничество
"лотерея", "быстрый выигрыш", "выигрыш", "приз", "деньги", "халява", "прибыль", "заработок", "зп", "подработка", "легкий заработок", "лотерея", "быстрый выигрыш", "выигрыш", "приз", "деньги", "халява", "прибыль", "заработок", "зп", "подработка", "легкий заработок",
......
# Функция для создания базы данных и таблиц
import sqlite3
def create_db():
db_path = 'users.db'
# Подключаемся к базе данных (если она не существует, она будет создана)
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Проверка, существует ли таблица (в случае первого запуска создадим её)
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
result = cursor.fetchone()
if not result:
# Если таблица users не существует, создаём её
cursor.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
username TEXT,
messages_checked INTEGER DEFAULT 0
)
''')
# Создание таблицы для забаненных пользователей
cursor.execute('''
CREATE TABLE banned_users (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
username TEXT,
ban_reason TEXT
)
''')
conn.commit()
conn.close()
# Функция для добавления пользователя в базу данных
def add_user(user_id, first_name, last_name, username):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO users (id, first_name, last_name, username)
VALUES (?, ?, ?, ?)
''', (user_id, first_name, last_name, username))
conn.commit()
conn.close()
# Функция для проверки, есть ли пользователь в базе данных
def user_exists(user_id):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
cursor.execute('SELECT id FROM users WHERE id = ?', (user_id,))
result = cursor.fetchone()
conn.close()
return result is not None
# Функция для перемещения пользователя в таблицу забаненных
def ban_user(user_id, first_name, last_name, username, ban_reason):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
# Добавляем в таблицу забаненных
cursor.execute('''
INSERT INTO banned_users (id, first_name, last_name, username, ban_reason)
VALUES (?, ?, ?, ?, ?)
''', (user_id, first_name, last_name, username, ban_reason))
# Удаляем из таблицы активных пользователей
cursor.execute('DELETE FROM users WHERE id = ?', (user_id,))
conn.commit()
conn.close()
def is_user_banned(user_id):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
cursor.execute('SELECT id FROM banned_users WHERE id = ?', (user_id,))
result = cursor.fetchone()
conn.close()
return result is not None
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment