from celery import shared_task import httpx from loguru import logger TELEGRAM_API_BASE = "https://api.telegram.org/bot{token}/{method}" def _build_keyboard(keyboard: dict | None) -> dict | None: if not keyboard: return None rows = [] for row in keyboard.get("rows", []): rows.append([{"text": btn["text"], "url": btn["url"]} for btn in row]) return {"inline_keyboard": rows} @shared_task def send_post_task(token: str, chat_id: int, payload: dict): """Отправка поста через Bot API. payload: {type, text, media_file_id, parse_mode, keyboard} keyboard: {rows: [[{text, url}, ...], ...]} """ t = payload.get("type", "text") reply_markup = _build_keyboard(payload.get("keyboard")) method = "sendMessage" data: dict = {"chat_id": chat_id} if t == "text": method = "sendMessage" data.update({"text": payload.get("text", ""), "parse_mode": payload.get("parse_mode")}) elif t == "photo": method = "sendPhoto" data.update({"photo": payload.get("media_file_id"), "caption": payload.get("text", ""), "parse_mode": payload.get("parse_mode")}) elif t == "video": method = "sendVideo" data.update({"video": payload.get("media_file_id"), "caption": payload.get("text", ""), "parse_mode": payload.get("parse_mode")}) elif t == "animation": method = "sendAnimation" data.update({"animation": payload.get("media_file_id"), "caption": payload.get("text", ""), "parse_mode": payload.get("parse_mode")}) if reply_markup: data["reply_markup"] = reply_markup url = TELEGRAM_API_BASE.format(token=token, method=method) with httpx.Client(timeout=30) as client: r = client.post(url, json=data) try: r.raise_for_status() logger.info("Sent post to {} via {}", chat_id, method) return r.json() except httpx.HTTPStatusError as e: logger.error("Telegram send failed: {} :: {}", e, r.text) raise