diff --git a/collect_all_members.py b/collect_all_members.py
new file mode 100644
index 0000000..d12073f
--- /dev/null
+++ b/collect_all_members.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+"""
+Сбор всех участников группы в базу данных
+Использование: python collect_all_members.py
+"""
+import asyncio
+import logging
+import aiohttp
+from aiohttp_socks import ProxyConnector
+from sqlalchemy import select, func
+from database.db import AsyncSessionLocal, init_db
+from database.models import User
+from config import BOT_TOKEN, ADMIN_CHAT_ID, get_proxy_url
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+async def collect_all_members():
+ """Собрать всех участников группы"""
+
+ await init_db()
+
+ proxy_url = get_proxy_url()
+ connector = ProxyConnector.from_url(proxy_url)
+
+ async with aiohttp.ClientSession(connector=connector) as session:
+ # Получаем всех участников через getChatMembers
+ # Telegram API позволяет получать по 100 за раз
+ all_members = []
+ offset = 0
+ limit = 100
+
+ logger.info(f'🔄 Начинаем сбор участников...')
+
+ while True:
+ try:
+ url = f"https://api.telegram.org/bot{BOT_TOKEN}/getChatMembers"
+ params = {
+ "chat_id": ADMIN_CHAT_ID,
+ "offset": offset,
+ "limit": limit
+ }
+
+ async with session.get(url, params=params) as resp:
+ result = await resp.json()
+
+ if not result.get('ok'):
+ logger.error(f'Ошибка API: {result}')
+ break
+
+ members = result.get('result', [])
+ if not members:
+ break
+
+ all_members.extend(members)
+ offset += limit
+
+ logger.info(f'Загружено {len(all_members)} участников...')
+
+ # Если загрузили меньше чем лимит — это конец
+ if len(members) < limit:
+ break
+
+ except Exception as e:
+ logger.error(f'Ошибка при загрузке: {e}')
+ break
+
+ logger.info(f'✅ Всего загружено: {len(all_members)}')
+
+ # Добавляем в базу
+ async with AsyncSessionLocal() as db_session:
+ added = 0
+ updated = 0
+
+ for member in all_members:
+ user_data = member.get('user', {})
+ user_id = user_data.get('id')
+
+ if not user_id:
+ continue
+
+ user = await db_session.get(User, user_id)
+
+ if not user:
+ # Новый пользователь
+ user = User(
+ user_id=user_id,
+ username=user_data.get('username'),
+ first_name=user_data.get('first_name'),
+ last_name=user_data.get('last_name'),
+ verified=False, # Пока не верифицирован
+ )
+ db_session.add(user)
+ added += 1
+ else:
+ # Обновляем данные
+ if user_data.get('username') and user.username != user_data.get('username'):
+ user.username = user_data.get('username')
+ updated += 1
+ if user_data.get('first_name') and user.first_name != user_data.get('first_name'):
+ user.first_name = user_data.get('first_name')
+ updated += 1
+
+ await db_session.commit()
+
+ # Статистика
+ total = (await db_session.execute(select(func.count(User.user_id)))).scalar()
+
+ logger.info(f'✅ Сбор завершён!')
+ logger.info(f' Добавлено: {added}')
+ logger.info(f' Обновлено: {updated}')
+ logger.info(f' Всего в базе: {total}')
+
+
+if __name__ == '__main__':
+ asyncio.run(collect_all_members())
diff --git a/data/service_images/police_2a8a48fc857d4cf78a10583d6820f1be.png b/data/service_images/police_2a8a48fc857d4cf78a10583d6820f1be.png
new file mode 100644
index 0000000..c2da00a
Binary files /dev/null and b/data/service_images/police_2a8a48fc857d4cf78a10583d6820f1be.png differ
diff --git a/data/service_images/utility_508733a4ff614d18be9424936c45b57f.png b/data/service_images/utility_508733a4ff614d18be9424936c45b57f.png
new file mode 100644
index 0000000..90a9a4f
Binary files /dev/null and b/data/service_images/utility_508733a4ff614d18be9424936c45b57f.png differ
diff --git a/handlers/users.py b/handlers/users.py
index 8ac545a..cd6137e 100644
--- a/handlers/users.py
+++ b/handlers/users.py
@@ -24,15 +24,9 @@ router = Router()
async def cmd_start(message: Message):
"""Команда /start (ТОЛЬКО В ЛИЧКЕ!)"""
from utils.ui_styles import get_level_badge
- from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
# Проверяем что это личка
if message.chat.type != 'private':
- await message.answer(
- '💡 Бот работает только в личных сообщениях!\n\n'
- 'Нажмите на имя бота сверху и напишите /start в личке',
- parse_mode='HTML'
- )
return
user_id = message.from_user.id
@@ -44,62 +38,14 @@ async def cmd_start(message: Message):
user = result.scalar_one_or_none()
if not user:
- # Создаём нового пользователя
- user = User(
- user_id=user_id,
- username=message.from_user.username,
- first_name=message.from_user.first_name,
- last_name=message.from_user.last_name,
- )
- session.add(user)
- await session.commit()
-
- # 🔴 НОВОЕ СООБЩЕНИЕ С КНОПКАМИ (БЕЗ !)
- welcome_text = f'''🔴 ДОБРО ПОЖАЛОВАТЬ
-
-👋 Привет, {message.from_user.first_name}!
-
-Я — домовой бот нашего дома.
-
-🏠 Что я умею:
-• 📞 Телефоны экстренных служб
-• 👷 Проверенные мастера
-• 📅 График отключений
-• 💰 Напоминания о платежах
-• 🏆 Рейтинг и достижения
-• 📋 Опросы и голосования
-
-⚠️ ВАЖНО:
-Для полного доступа пройдите верификацию!
-
-📝 Как пройти верификацию:
-
-Шаг 1: Отправьте номер квартиры
-Примеры: 45, 12А, 100-1
-
-Шаг 2: (опционально) Отправьте телефон
-Пример: +79991234567
-
-Шаг 3: Дождитесь подтверждения админа
-
-После верификации откроются все функции! 🎉'''
-
- # Кнопки для быстрого старта
- kb = ReplyKeyboardMarkup(
- keyboard=[
- [KeyboardButton(text='📞 Экстренные телефоны')],
- [KeyboardButton(text='📜 Правила чата'), KeyboardButton(text='❓ Помощь')],
- ],
- resize_keyboard=True
- )
-
- await message.answer(welcome_text, parse_mode='HTML', reply_markup=kb)
-
- else:
- # Обновляем имя
- user.username = message.from_user.username
- user.first_name = message.from_user.first_name
- user.last_name = message.from_user.last_name
+ # Пользователя нет в базе - ИГНОР!
+ logger.info(f'Пользователь {user_id} не в базе - игнорируем /start')
+ return
+
+ # Пользователь в базе - обновляем имя
+ user.username = message.from_user.username
+ user.first_name = message.from_user.first_name
+ user.last_name = message.from_user.last_name
# Проверяем статус
is_admin = user.is_admin or (user_id == config.ADMIN_USER_ID)
@@ -182,15 +128,20 @@ async def cmd_start(message: Message):
@router.message(Command('help'))
async def cmd_help(message: Message):
"""Справка по командам (для жильцов)"""
- from utils.ui_styles import get_colored_header, get_level_badge, get_user_level_with_ig
+ from utils.ui_styles import get_colored_header, get_level_badge
from database.models import InitiativeGroup
user_id = message.from_user.id
async with AsyncSessionLocal() as session:
user = await session.get(User, user_id)
+ # Проверяем есть ли в базе
+ if not user:
+ logger.info(f'Пользователь {user_id} не в базе - игнорируем /help')
+ return
+
# Определяем уровень
- if user and user.verified:
+ if user.verified:
ig_stmt = select(InitiativeGroup).where(
InitiativeGroup.user_id == user_id,
InitiativeGroup.is_active == True