Remove non-functional MAX auto-reaction, add real TG auto-reaction

MAX Bot API has no reaction endpoint (confirmed 404 in production logs),
so drop the dead code path entirely instead of eating a warning every post.

Telegram's setMessageReaction is a real Bot API method (verified against
aiogram 3.21.0, the pinned version) - wire it up as a non-fatal
best-effort call after a successful send, mirroring the same
try/except-and-log pattern MAX already used.
This commit is contained in:
2026-08-14 22:14:31 +05:00
parent 6a7a995d5f
commit be01558ddb
4 changed files with 22 additions and 23 deletions
+3 -3
View File
@@ -39,9 +39,6 @@ MAX_BOT_TOKEN=your_max_bot_token_here
MAX_CHAT_ID=123456 MAX_CHAT_ID=123456
# MAX API Base URL # MAX API Base URL
MAX_API_BASE_URL=https://platform-api2.max.ru MAX_API_BASE_URL=https://platform-api2.max.ru
# MAX Auto Reaction emoji on published post
MAX_AUTO_REACTION=👍
MAX_AUTO_REACTION_ENABLED=true
# ========================================== # ==========================================
# Polling, Reporting & Maintenance # Polling, Reporting & Maintenance
@@ -83,6 +80,9 @@ FOOTER_TEXT=
COMMON_TAGS=#redairsoft #страйкбол COMMON_TAGS=#redairsoft #страйкбол
# Make the first line of the post bold # Make the first line of the post bold
FORMAT_FIRST_LINE_BOLD=true FORMAT_FIRST_LINE_BOLD=true
# Telegram auto-reaction emoji on published posts (real Bot API method, unlike MAX)
TG_AUTO_REACTION=👍
TG_AUTO_REACTION_ENABLED=true
# Logging Level (DEBUG, INFO, WARNING, ERROR) # Logging Level (DEBUG, INFO, WARNING, ERROR)
LOG_LEVEL=INFO LOG_LEVEL=INFO
+2 -3
View File
@@ -34,9 +34,6 @@ class Settings(BaseSettings):
max_bot_token: str = "" max_bot_token: str = ""
max_chat_id: str = "" # Destination chat ID in MAX max_chat_id: str = "" # Destination chat ID in MAX
max_api_base_url: str = "https://platform-api2.max.ru" max_api_base_url: str = "https://platform-api2.max.ru"
max_auto_reaction: str = "👍"
max_auto_reaction_enabled: bool = True
max_reaction_path_template: str = "/messages/{message_id}/reactions"
max_video_ready_attempts: int = 6 max_video_ready_attempts: int = 6
max_video_ready_delay_sec: float = 8.0 max_video_ready_delay_sec: float = 8.0
@@ -67,6 +64,8 @@ class Settings(BaseSettings):
footer_text: str = "" footer_text: str = ""
common_tags: str = "" common_tags: str = ""
format_first_line_bold: bool = True format_first_line_bold: bool = True
tg_auto_reaction: str = "👍"
tg_auto_reaction_enabled: bool = True
# Logging # Logging
log_level: str = "INFO" log_level: str = "INFO"
-16
View File
@@ -129,11 +129,6 @@ class MAXAPIClient:
raise RuntimeError(f"MAX upload {resp.status}: {data}") raise RuntimeError(f"MAX upload {resp.status}: {data}")
return data return data
async def react(self, path_template: str, message_id: str, reaction: str) -> None:
path = path_template.format(message_id=message_id)
payload = {"reaction": reaction}
await self.request("POST", path, json=payload)
class MAXPoster: class MAXPoster:
def __init__(self) -> None: def __init__(self) -> None:
@@ -295,17 +290,6 @@ class MAXPoster:
msg_obj = res.get("message") if isinstance(res.get("message"), dict) else res msg_obj = res.get("message") if isinstance(res.get("message"), dict) else res
first_url = self.message_url_from_response(msg_obj) first_url = self.message_url_from_response(msg_obj)
# Try auto reaction if enabled
if settings.max_auto_reaction_enabled and settings.max_auto_reaction:
try:
await client.react(
settings.max_reaction_path_template,
first_mid,
settings.max_auto_reaction,
)
except Exception as exc:
logger.warning("MAX auto reaction failed: {}", exc)
for group in media_groups[1:]: for group in media_groups[1:]:
attachments = await self.upload_media_group(client, group) attachments = await self.upload_media_group(client, group)
if not attachments: if not attachments:
+17 -1
View File
@@ -9,7 +9,7 @@ from aiogram import Bot
from aiogram.client.session.aiohttp import AiohttpSession from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer from aiogram.client.telegram import TelegramAPIServer
from aiogram.exceptions import TelegramRetryAfter from aiogram.exceptions import TelegramRetryAfter
from aiogram.types import FSInputFile, InputMediaPhoto, InputMediaVideo from aiogram.types import FSInputFile, InputMediaPhoto, InputMediaVideo, ReactionTypeEmoji
try: try:
from .config import settings from .config import settings
from .media_processor import ProcessedMedia from .media_processor import ProcessedMedia
@@ -119,6 +119,18 @@ class TelegramPoster:
await asyncio.sleep(2 ** attempt) await asyncio.sleep(2 ** attempt)
raise RuntimeError("Telegram retries exhausted") raise RuntimeError("Telegram retries exhausted")
async def set_reaction(self, message_id: int) -> None:
if not (settings.tg_auto_reaction_enabled and settings.tg_auto_reaction and self.bot):
return
try:
await self.bot.set_message_reaction(
chat_id=self.chat_id,
message_id=message_id,
reaction=[ReactionTypeEmoji(emoji=settings.tg_auto_reaction)],
)
except Exception as exc:
logger.warning("Telegram auto reaction failed: {}", exc)
async def upload_media_for_file_ids( async def upload_media_for_file_ids(
self, media_items: list[ProcessedMedia] self, media_items: list[ProcessedMedia]
) -> dict[str, str]: ) -> dict[str, str]:
@@ -405,6 +417,8 @@ class TelegramPoster:
mids = await self.send_rich_message(rich_msg) mids = await self.send_rich_message(rich_msg)
url = tg_message_url(self.chat_id, mids[0]) if mids else None url = tg_message_url(self.chat_id, mids[0]) if mids else None
logger.info("Sent Telegram rich message: {}", mids) logger.info("Sent Telegram rich message: {}", mids)
if mids:
await self.set_reaction(mids[0])
return mids, url return mids, url
except RichMessageUnavailable as exc: except RichMessageUnavailable as exc:
logger.warning("Telegram sendRichMessage failed: {}. Falling back to standard send.", exc) logger.warning("Telegram sendRichMessage failed: {}. Falling back to standard send.", exc)
@@ -412,4 +426,6 @@ class TelegramPoster:
mids = await self.send_media_post(formatted_text, valid_media, file_ids) mids = await self.send_media_post(formatted_text, valid_media, file_ids)
url = tg_message_url(self.chat_id, mids[0]) if mids else None url = tg_message_url(self.chat_id, mids[0]) if mids else None
logger.info("Sent Telegram message: {}", mids) logger.info("Sent Telegram message: {}", mids)
if mids:
await self.set_reaction(mids[0])
return mids, url return mids, url