import logging
import re
from aiogram import Router, F
from aiogram.types import Message
from aiogram.filters import Command
from services.personal_inbox_service import PersonalInboxService
import config
logger = logging.getLogger(__name__)
router = Router()
# Регулярка для поиска URL
URL_REGEX = re.compile(r'(https?://[^\s]+)')
@router.message(F.chat.type == 'private', Command('digest'))
@router.message(F.chat.type == 'private', Command('digest_send'))
async def cmd_send_digest(message: Message):
"""Ручной запуск отправки дайджеста"""
if message.from_user.id != config.ADMIN_USER_ID:
return
await message.answer("🔄 Собираю еженедельный дайджест...", parse_mode='HTML')
success = await PersonalInboxService.send_weekly_digest(message.bot)
if not success:
await message.answer("ℹ️ Нет активных (неотправленных) записей в вашем инбоксе.")
@router.message(F.chat.type == 'private', Command('digest_list'))
async def cmd_list_digest(message: Message):
"""Показать список текущих записей в инбоксе"""
if message.from_user.id != config.ADMIN_USER_ID:
return
items = await PersonalInboxService.get_pending_items(config.ADMIN_USER_ID)
if not items:
await message.answer("📥 Ваш инбокс дайджеста пуст.")
return
lines = [f"📥 Текущие записи в инбоксе ({len(items)}):\n"]
for idx, item in enumerate(items, 1):
date_str = item.created_at.strftime('%d.%m %H:%M')
line = f"{idx}. [{date_str}] "
if item.url:
line += f'Ссылка'
else:
line += "Текст"
if item.message_text:
# Обрезаем длинный текст
short_text = item.message_text[:60] + "..." if len(item.message_text) > 60 else item.message_text
line += f": {short_text}"
lines.append(line)
lines.append("\n✍️ Для ручной отправки дайджеста введите /digest. Для очистки - /digest_clear.")
await message.answer("\n".join(lines), parse_mode='HTML', disable_web_page_preview=True)
@router.message(F.chat.type == 'private', Command('digest_clear'))
async def cmd_clear_digest(message: Message):
"""Очистить инбокс"""
if message.from_user.id != config.ADMIN_USER_ID:
return
success = await PersonalInboxService.clear_pending_items(config.ADMIN_USER_ID)
if success:
await message.answer("🧹 Ваш инбокс успешно очищен (все записи помечены как отправленные).")
else:
await message.answer("❌ Произошла ошибка при очистке инбокса.")
@router.message(F.chat.type == 'private')
async def handle_private_inbox(message: Message):
"""Обработчик всех входящих личных сообщений от админа для сохранения в инбокс"""
if message.from_user.id != config.ADMIN_USER_ID:
# Для других пользователей пропускаем или выдаем стандартный ответ
return
# Игнорируем команды, которые могли проскочить
if message.text and message.text.startswith('/'):
return
# Собираем текст
text = message.text or message.caption or ""
# Пытаемся вытащить URL из сущностей aiogram
urls = []
entities = message.entities or message.caption_entities or []
for entity in entities:
if entity.type == 'url':
urls.append(text[entity.offset:entity.offset+entity.length])
elif entity.type == 'text_link':
urls.append(entity.url)
# Если aiogram не нашел сущностей, ищем регуляркой
if not urls:
found = URL_REGEX.findall(text)
if found:
urls.extend(found)
# Определяем тип медиа
media_type = 'text'
if message.photo:
media_type = 'photo'
elif message.video:
media_type = 'video'
elif message.document:
media_type = 'document'
primary_url = urls[0] if urls else None
# Добавляем в инбокс
success = await PersonalInboxService.add_to_inbox(
user_id=config.ADMIN_USER_ID,
text=text,
url=primary_url,
media_type=media_type
)
if success:
items = await PersonalInboxService.get_pending_items(config.ADMIN_USER_ID)
count = len(items)
reply_msg = "📥 Добавлено в инбокс дайджеста!"
if primary_url:
reply_msg += f"\n🔗 Распознана ссылка: {primary_url}"
reply_msg += f"\n\n📂 Всего записей в очереди: {count}"
await message.answer(reply_msg, parse_mode='HTML', disable_web_page_preview=True)
else:
await message.answer("❌ Произошла ошибка при сохранении сообщения в инбокс.")