56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
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 |