Files
tg-digest-docker/delivery.py
Тимур Абайдулин ba1245a06c init
2026-02-07 16:31:46 +03:00

110 lines
3.7 KiB
Python

"""
Доставка дайджеста: 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}")