Files
TG_autoposter/app/handlers/sender.py
2025-12-18 05:55:32 +09:00

125 lines
5.1 KiB
Python
Raw Permalink 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.

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")