domovoy_bot/collect_all_members.py
Admin 9cee4e8d1f v1.22 Безопасность - белый список
🔒 БЕЗОПАСНОСТЬ:
• Бот работает ТОЛЬКО с пользователями из базы
• /start - игнор если нет в базе
• /help - игнор если нет в базе
• Верифицированные - полный доступ
• Неверифицированные - стимул пройти верификацию

📁 ФАЙЛЫ:
• handlers/users.py: проверка базы
• collect_all_members.py: скрипт сбора

🎯 СТИМУЛ:
• Хочешь бота? → Пройди верификацию!
• Админы, ИГ, верифицированные - работают
• Остальные - игнор

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-11 12:22:50 +00:00

117 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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())