125 lines
5.1 KiB
Python
125 lines
5.1 KiB
Python
from telegram import Update
|
||
from telegram.ext import ContextTypes
|
||
from app.database import AsyncSessionLocal
|
||
from app.database.repository import GroupRepository, MessageRepository, MessageGroupRepository
|
||
from app.utils.keyboards import get_back_keyboard, CallbackType
|
||
from app.utils import can_send_message
|
||
from datetime import datetime, timedelta
|
||
import logging
|
||
import asyncio
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
async def send_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||
"""Отправить сообщение в группы с учетом slow mode"""
|
||
query = update.callback_query
|
||
|
||
# Парсим callback: send_msg_<message_id>
|
||
callback_data = query.data
|
||
if callback_data.startswith("send_msg_"):
|
||
message_id = int(callback_data.split("_")[2])
|
||
else:
|
||
await query.answer("❌ Ошибка обработки", show_alert=True)
|
||
return
|
||
|
||
async with AsyncSessionLocal() as session:
|
||
msg_repo = MessageRepository(session)
|
||
group_repo = GroupRepository(session)
|
||
mg_repo = MessageGroupRepository(session)
|
||
|
||
message = await msg_repo.get_message(message_id)
|
||
if not message:
|
||
await query.answer("❌ Сообщение не найдено", show_alert=True)
|
||
return
|
||
|
||
# Получить группы, куда нужно отправить
|
||
message_groups = await mg_repo.get_message_groups_to_send(message_id)
|
||
|
||
if not message_groups:
|
||
await query.answer("✅ Сообщение уже отправлено во все группы", show_alert=True)
|
||
return
|
||
|
||
await query.answer()
|
||
await query.edit_message_text(
|
||
f"📤 Начинаю отправку '{message.title}' в {len(message_groups)} групп(ы)...\n\n"
|
||
"⏳ Это может занять некоторое время в зависимости от slow mode."
|
||
)
|
||
|
||
# Отправляем в каждую группу
|
||
sent_count = 0
|
||
failed_count = 0
|
||
total_wait = 0
|
||
|
||
for mg in message_groups:
|
||
try:
|
||
# Проверяем slow mode
|
||
can_send, wait_time = await can_send_message(mg.group)
|
||
|
||
if not can_send:
|
||
# Ждем
|
||
await query.edit_message_text(
|
||
f"📤 Отправка '{message.title}'...\n\n"
|
||
f"✅ Отправлено: {sent_count}\n"
|
||
f"❌ Ошибок: {failed_count}\n"
|
||
f"⏳ Ожидание {wait_time}s перед отправкой в {mg.group.title}..."
|
||
)
|
||
await asyncio.sleep(wait_time)
|
||
total_wait += wait_time
|
||
|
||
# Отправляем сообщение
|
||
await context.bot.send_message(
|
||
chat_id=mg.group.chat_id,
|
||
text=message.text,
|
||
parse_mode=message.parse_mode
|
||
)
|
||
|
||
# Отмечаем как отправленное
|
||
async with AsyncSessionLocal() as session:
|
||
mg_repo = MessageGroupRepository(session)
|
||
await mg_repo.mark_as_sent(mg.id)
|
||
group_repo = GroupRepository(session)
|
||
await group_repo.update_last_message_time(mg.group.id)
|
||
|
||
sent_count += 1
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при отправке в группу {mg.group.chat_id}: {e}")
|
||
async with AsyncSessionLocal() as session:
|
||
mg_repo = MessageGroupRepository(session)
|
||
await mg_repo.mark_as_sent(mg.id, error=str(e))
|
||
failed_count += 1
|
||
|
||
# Обновляем сообщение каждые 5 отправок
|
||
if sent_count % 5 == 0:
|
||
await query.edit_message_text(
|
||
f"📤 Отправка '{message.title}'...\n\n"
|
||
f"✅ Отправлено: {sent_count}\n"
|
||
f"❌ Ошибок: {failed_count}"
|
||
)
|
||
|
||
# Финальное сообщение
|
||
final_text = f"✅ <b>Отправка завершена</b>\n\n"
|
||
final_text += f"✅ Успешно: {sent_count}\n"
|
||
final_text += f"❌ Ошибок: {failed_count}\n"
|
||
if total_wait > 0:
|
||
final_text += f"⏳ Всего ожидалось: {total_wait}s"
|
||
|
||
await query.edit_message_text(
|
||
final_text,
|
||
parse_mode='HTML',
|
||
reply_markup=get_back_keyboard()
|
||
)
|
||
|
||
|
||
async def discover_groups(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||
"""
|
||
Обнаружить все группы, в которых есть бот
|
||
Этот метод вызывается при запуске или по команде
|
||
"""
|
||
# Получить список всех чатов, в которых есть бот
|
||
# NOTE: python-telegram-bot не имеет встроенного способа получить все чаты
|
||
# Это нужно реализовать через webhook или polling с сохранением информации о новых группах
|
||
|
||
logger.info("Функция обнаружения групп - необходимо добавить обработчик my_chat_member")
|