303 lines
14 KiB
Python
303 lines
14 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
🏠 Домовой Бот — Telegram-бот для чата многоквартирного дома
|
||
|
||
ВЕРСИЯ: v1.2 — Чёрный список ссылок
|
||
ДАТА ФИКСАЦИИ: 26 февраля 2026 г.
|
||
СТАТУС: ✅ Реализовано
|
||
|
||
РЕАЛИЗОВАНО В v1.0:
|
||
- Регистрация и верификация жильцов
|
||
- Рейтинг активности (уровни: Новичок → Сосед → Активист → Лидер)
|
||
- Детект шпионов (Score 0-100, 8 факторов)
|
||
- Анти-мат система (3 предупреждения → бан)
|
||
- Админ-панель с рассылкой
|
||
- Учёт квартир (несколько жильцов на квартиру)
|
||
- Телефоны экстренных служб и мастеров
|
||
- Еженедельный экспорт JSON
|
||
- Прокси (socks5) для обхода РКН
|
||
|
||
РЕАЛИЗОВАНО В v1.1 (26.02.2026):
|
||
- ✅ Опросы и голосования (/poll_create, /poll_end, /polls)
|
||
- ✅ Inline-кнопки для голосования
|
||
- ✅ Подсчёт голосов в реальном времени
|
||
- ✅ Результаты с визуальной шкалой
|
||
- ✅ Защита от повторного голосования
|
||
|
||
РЕАЛИЗОВАНО В v1.2 (26.02.2026):
|
||
- ✅ Чёрный список доменов (data/bad_domains.json)
|
||
- ✅ Чёрный список паттернов и ключевых слов
|
||
- ✅ Авто-удаление спам-сообщений
|
||
- ✅ Система предупреждений (3 → бан)
|
||
- ✅ Уведомление админа о спаме
|
||
- ✅ Команды управления ЧС (/add_domain, /domains, /warnings...)
|
||
|
||
РЕАЛИЗОВАНО В v1.3 (26.02.2026):
|
||
- ✅ Анти-спам лимиты (10 сообщений за 60 сек)
|
||
- ✅ Авто-удаление флуда
|
||
- ✅ Система предупреждений (2 → мут на 30 мин)
|
||
- ✅ Команды мута/размута (/mute, /unmute, /muted)
|
||
- ✅ Проверка истечения мута
|
||
|
||
РЕАЛИЗОВАНО В v1.4 (26.02.2026):
|
||
- ✅ Расписание отключений (вода, свет, отопление, газ, лифт)
|
||
- ✅ Пошаговое создание событий (/schedule_add)
|
||
- ✅ Просмотр расписания (/график)
|
||
- ✅ Авто-напоминания за 1 час до начала
|
||
- ✅ 6 типов отключений с emoji
|
||
|
||
РЕАЛИЗОВАНО В v1.5 (26.02.2026):
|
||
- ✅ Доска объявлений (6 категорий: продам, куплю, отдам, потеряно, нашлось, услуга)
|
||
- ✅ Пошаговое создание объявлений (/ad)
|
||
- ✅ Просмотр всех объявлений (/ads)
|
||
- ✅ Авто-удаление через 7 дней
|
||
- ✅ Только для верифицированных жильцов
|
||
|
||
РЕАЛИЗОВАНО В v1.6 (26.02.2026):
|
||
- ✅ Напоминания о платежах ЖКХ (8 типов: электро, вода, отопление, газ, жильё, мусор, интернет, другое)
|
||
- ✅ Пошаговое создание напоминаний (/payment_add)
|
||
- ✅ Просмотр всех платежей (/payments)
|
||
- ✅ Авто-рассылка 5 и 9 числа в 09:00
|
||
- ✅ Ссылки на оплату (Госуслуги, Сбербанк, Тинькофф)
|
||
|
||
РЕАЛИЗОВАНО В v1.7 (26.02.2026):
|
||
- ✅ Детект мультиаккаунтов (анализ активности, паттернов сообщений)
|
||
- ✅ Проверка всех пользователей (/multicheck)
|
||
- ✅ Проверка квартир (/check_apt)
|
||
- ✅ Статистика (/multistats)
|
||
- ✅ Сброс score (/clear_multiscore)
|
||
- ✅ Связывание аккаунтов (/link_accounts)
|
||
|
||
РЕАЛИЗОВАНО В v1.8 (26.02.2026):
|
||
- ✅ Облако тегов тем чата (18 тем: лифты, парковка, уборка, соседи...)
|
||
- ✅ Авто-классификация сообщений
|
||
- ✅ Статистика по темам (/topics, /top_topics)
|
||
- ✅ Еженедельный отчёт (/weekly_report)
|
||
|
||
РЕАЛИЗОВАНО В v1.9 (26.02.2026):
|
||
- ✅ Рейтинг токсичности (4 категории: оскорбления, агрессия, угрозы, дискриминация)
|
||
- ✅ Toxicity Score 0-100 для каждого пользователя
|
||
- ✅ Топ токсичных пользователей (/toxic_top)
|
||
- ✅ Статистика по пользователю (/toxic_stats)
|
||
- ✅ Жалобы на пользователей (/complaint)
|
||
- ✅ Авто-анализ сообщений и уведомления
|
||
|
||
РЕАЛИЗОВАНО В v1.10 (26.02.2026):
|
||
- ✅ История версий профиля (авто-логирование изменений username, first_name, last_name)
|
||
- ✅ Команда /history — история конкретного пользователя
|
||
- ✅ Команда /all_history — все изменения за период
|
||
- ✅ Команда /field_history — история по полю
|
||
- ✅ Команда /history_stats — статистика изменений
|
||
|
||
РЕАЛИЗОВАНО В v1.11 (27.02.2026):
|
||
- ✅ Веб-интерфейс админа на FastAPI
|
||
- ✅ Дашборд со статистикой
|
||
- ✅ Страница пользователей с поиском
|
||
- ✅ Страница экспорта данных
|
||
- ✅ API endpoints (/api/stats, /api/users, /api/export)
|
||
- ✅ HTTP Basic авторизация
|
||
|
||
РЕАЛИЗОВАНО В v1.12 (27.02.2026):
|
||
- ✅ Достижения жильцов (16 достижений в 9 категориях)
|
||
- ✅ Авто-выдача достижений за активность, рейтинг, верификацию
|
||
- ✅ Команда /achievements — свои достижения
|
||
- ✅ Команда /achievements_top — топ по достижениям
|
||
- ✅ Уведомления о новых достижениях
|
||
|
||
РЕАЛИЗОВАНО В v1.13 (27.02.2026):
|
||
- ✅ Система благодарностей (/thank @username)
|
||
- ✅ +10 к рейтингу за благодарность
|
||
- ✅ Достижение "Помощник" при первой благодарности
|
||
- ✅ Ограничение: 1 благодарность в день
|
||
- ✅ Топ и история благодарностей
|
||
|
||
РЕАЛИЗОВАНО В v1.14 (27.02.2026):
|
||
- ✅ Календарь событий дома (собрания, субботники, праздники)
|
||
- ✅ Создание событий (/event_add)
|
||
- ✅ Запись на участие (/join, /leave)
|
||
- ✅ Просмотр событий (/events, /my_events)
|
||
- ✅ Список участников (/participants)
|
||
- ✅ Авто-напоминания за 24 часа
|
||
|
||
🎉 ВСЕ ФУНКЦИИ v1.x РЕАЛИЗОВАНЫ! 🎉
|
||
|
||
РЕАЛИЗОВАНО В v2.1 (27.02.2026):
|
||
- ✅ Инициативная группа (отдельная сущность от админов)
|
||
- ✅ Модель InitiativeGroup в БД
|
||
- ✅ Команды: /ig_add, /ig_remove, /ig_list, /ig_stats, /ig_check
|
||
- ✅ Рассылка только для ИГ: /ig_broadcast
|
||
- ✅ Декораторы для ИГ
|
||
|
||
🚀 НАЧАТА РАЗРАБОТКА v2.x! 🚀
|
||
|
||
ПЛАН РАЗРАБОТКИ (v2.2 — v2.x):
|
||
См. файл DEVELOPMENT_PLAN.md и VERSIONS.md
|
||
|
||
БЕКАПЫ ВЕРСИЙ:
|
||
backups/versions/vX.X_YYYY-MM-DD/
|
||
|
||
АВТОРЫ: matrixhasyou + Qwen Code
|
||
"""
|
||
import logging
|
||
import asyncio
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# Добавляем путь к проекту
|
||
BASE_DIR = Path(__file__).resolve().parent
|
||
sys.path.insert(0, str(BASE_DIR))
|
||
|
||
from aiogram import Bot, Dispatcher
|
||
from aiogram.client.default import DefaultBotProperties
|
||
from aiogram.enums import ParseMode
|
||
from aiogram.filters import Command
|
||
from aiogram.types import Message
|
||
from aiogram.client.session.aiohttp import AiohttpSession
|
||
from aiogram.fsm.storage.memory import MemoryStorage
|
||
|
||
from config import (
|
||
BOT_TOKEN, ADMIN_USER_ID, ADMIN_CHAT_ID, get_proxy_url,
|
||
USE_PROXY, PROXY_TYPE, PROXY_HOST, PROXY_PORT
|
||
)
|
||
from database.db import init_db
|
||
from handlers import admin_router, users_router, verification_router, chat_monitor_router, security_router, apartments_router, antimat_router, phones_router, polls_router, antispam_router, ratelimit_router, schedule_router, ads_router, payments_router, multicount_router, topics_router, toxicity_router, profile_history_router, achievements_router, thanks_router, events_router, initiative_group_router
|
||
from services.scheduler import Scheduler
|
||
from services.web_server import WebServerService
|
||
from database.models import ScheduledPost # Для новой модели
|
||
|
||
# Настройка логирования
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.FileHandler('logs/bot.log', encoding='utf-8'),
|
||
logging.StreamHandler()
|
||
]
|
||
)
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
# Функция create_bot_with_proxy перенесена в bot_instance.py
|
||
# Теперь используется глобальный экземпляр через get_bot()
|
||
|
||
|
||
async def on_startup(bot: Bot):
|
||
"""Действия при запуске"""
|
||
logger.info('🚀 Бот запускается...')
|
||
|
||
# Инициализация БД
|
||
await init_db()
|
||
logger.info('✅ База данных инициализирована')
|
||
|
||
# Инициализация модуля безопасности
|
||
from services.safety_guard import init_safety_module
|
||
safety_mode = init_safety_module(ADMIN_CHAT_ID)
|
||
if safety_mode == 'safe':
|
||
logger.warning('🔒🔒🔒 SAFETY MODE АКТИВИРОВАН — отправки в общий чат заблокированы!')
|
||
else:
|
||
logger.info(f'🔒 Режим безопасности: {safety_mode}')
|
||
|
||
# Запуск планировщика
|
||
scheduler = Scheduler(bot)
|
||
scheduler.start()
|
||
logger.info('✅ Планировщик задач запущен')
|
||
|
||
# Запуск веб-сервера
|
||
web_server = WebServerService(port=8000)
|
||
web_server.start()
|
||
logger.info(f'🌐 Веб-интерфейс: {web_server.get_url()}')
|
||
|
||
# Уведомление админа
|
||
try:
|
||
await bot.send_message(
|
||
ADMIN_USER_ID,
|
||
'✅ <b>Домовой бот запущен!</b>\n\n'
|
||
f'Прокси: {"✅" if USE_PROXY else "❌"}\n'
|
||
f'Веб-интерфейс: {web_server.get_url()}\n'
|
||
'Логин: admin\n'
|
||
f'Пароль: {ADMIN_USER_ID}\n\n'
|
||
'Использйте /admin для управления.',
|
||
parse_mode=ParseMode.HTML
|
||
)
|
||
except Exception as e:
|
||
logger.error(f'Не удалось уведомить админа о запуске: {e}')
|
||
|
||
|
||
async def on_shutdown(bot: Bot):
|
||
"""Действия при остановке"""
|
||
logger.info('🛑 Бот останавливается...')
|
||
|
||
try:
|
||
await bot.send_message(
|
||
ADMIN_USER_ID,
|
||
'⚠️ <b>Домовой бот остановлен</b>\n\n'
|
||
'Перезапустите бота.',
|
||
parse_mode=ParseMode.HTML
|
||
)
|
||
except Exception:
|
||
pass
|
||
|
||
# Закрываем сессию через глобальный модуль
|
||
from bot_instance import close_bot
|
||
await close_bot()
|
||
|
||
|
||
async def main():
|
||
"""Основная функция"""
|
||
# Используем глобальный экземпляр бота
|
||
from bot_instance import get_bot, close_bot
|
||
bot = get_bot()
|
||
|
||
# Создаём диспетчер с FSM storage (для состояний)
|
||
dp = Dispatcher(storage=MemoryStorage())
|
||
|
||
# Регистрируем роутеры
|
||
dp.include_router(admin_router)
|
||
dp.include_router(users_router)
|
||
dp.include_router(verification_router)
|
||
dp.include_router(chat_monitor_router)
|
||
dp.include_router(security_router)
|
||
dp.include_router(apartments_router)
|
||
dp.include_router(antimat_router)
|
||
dp.include_router(phones_router)
|
||
dp.include_router(polls_router)
|
||
dp.include_router(antispam_router)
|
||
dp.include_router(ratelimit_router)
|
||
dp.include_router(schedule_router)
|
||
dp.include_router(ads_router)
|
||
dp.include_router(payments_router)
|
||
dp.include_router(multicount_router)
|
||
dp.include_router(topics_router)
|
||
dp.include_router(toxicity_router)
|
||
dp.include_router(profile_history_router)
|
||
dp.include_router(achievements_router)
|
||
dp.include_router(thanks_router)
|
||
dp.include_router(events_router)
|
||
dp.include_router(initiative_group_router)
|
||
|
||
# V3.1 - Умные рассылки и дайджесты
|
||
from handlers.smart_broadcast import router as smart_broadcast_router
|
||
from handlers.digest import router as digest_router
|
||
|
||
dp.include_router(smart_broadcast_router)
|
||
dp.include_router(digest_router)
|
||
|
||
logger.info('✅ Зарегистрированы роутеры: умные рассылки, дайджесты')
|
||
|
||
# Регистрируем хуки
|
||
dp.startup.register(on_startup)
|
||
dp.shutdown.register(on_shutdown)
|
||
|
||
# Запуск
|
||
logger.info('🤖 Запуск бота...')
|
||
await dp.start_polling(bot)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
try:
|
||
asyncio.run(main())
|
||
except KeyboardInterrupt:
|
||
logger.info('🛑 Остановка по Ctrl+C')
|
||
except Exception as e:
|
||
logger.error(f'Критическая ошибка: {e}', exc_info=True)
|