""" Доставка дайджеста: Telegram (Избранное / бот) или файл. """ import logging from datetime import datetime from pathlib import Path import httpx from telethon import TelegramClient logger = logging.getLogger(__name__) SESSION_DIR = Path("/data") def _split_message(text: str, max_length: int = 4000) -> list[str]: if len(text) <= max_length: return [text] parts = [] current = "" for line in text.split("\n"): if len(current) + len(line) + 1 > max_length: if current: parts.append(current.strip()) current = line + "\n" else: current += line + "\n" if current.strip(): parts.append(current.strip()) return parts class DeliveryManager: def __init__(self, config: dict): self.cfg = config["delivery"] self.tg_cfg = config["telegram"] self.method = self.cfg["method"] self.max_length = self.cfg.get("max_message_length", 4000) async def deliver(self, digest: str) -> None: now = datetime.now().strftime("%d.%m.%Y %H:%M") header = f"📰 **Новостной дайджест** — {now}\n\n" full_text = header + digest if self.method == "saved_messages": await self._send_saved_messages(full_text) elif self.method == "bot": await self._send_via_bot(full_text) elif self.method == "file": self._save_to_file(full_text) else: raise ValueError(f"Неизвестный метод доставки: {self.method}") async def _send_saved_messages(self, text: str): session_path = SESSION_DIR / self.tg_cfg["session_name"] client = TelegramClient( str(session_path), self.tg_cfg["api_id"], self.tg_cfg["api_hash"], ) await client.connect() if not await client.is_user_authorized(): raise RuntimeError("Сессия не авторизована") parts = _split_message(text, self.max_length) me = await client.get_me() for i, part in enumerate(parts, 1): await client.send_message(me, part, parse_mode="md") logger.info(f"Отправлена часть {i}/{len(parts)} в Избранное") await client.disconnect() logger.info("✓ Дайджест отправлен в Избранное") async def _send_via_bot(self, text: str): token = self.cfg["bot_token"] chat_id = self.cfg["chat_id"] url = f"https://api.telegram.org/bot{token}/sendMessage" parts = _split_message(text, self.max_length) async with httpx.AsyncClient(timeout=30) as client: for i, part in enumerate(parts, 1): resp = await client.post( url, json={ "chat_id": chat_id, "text": part, "parse_mode": "Markdown", "disable_web_page_preview": True, }, ) if resp.status_code != 200: logger.error(f"Bot API: {resp.status_code} {resp.text}") else: logger.info(f"Часть {i}/{len(parts)} через бота") logger.info("✓ Дайджест отправлен через бота") def _save_to_file(self, text: str): output_dir = Path("/data/digests") output_dir.mkdir(parents=True, exist_ok=True) filename = datetime.now().strftime("digest_%Y%m%d_%H%M.md") filepath = output_dir / filename filepath.write_text(text, encoding="utf-8") logger.info(f"✓ Дайджест сохранён: {filepath}")