122 lines
4.7 KiB
Python
122 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Message utility functions for sending and editing Telegram messages.
|
|
Handles image caching, smooth transitions, and message editing logic.
|
|
"""
|
|
import logging
|
|
import os
|
|
from telegram import InlineKeyboardMarkup, InputMediaPhoto
|
|
from telegram.error import BadRequest
|
|
from .api_client import api_client
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def send_or_edit_with_image(query, text: str, reply_markup: InlineKeyboardMarkup,
|
|
image_path: str = None, parse_mode: str = 'HTML'):
|
|
"""
|
|
Send a message with an image (as caption) or edit existing message.
|
|
Uses edit_message_media for smooth transitions when changing images.
|
|
|
|
Args:
|
|
query: The callback query object
|
|
text: Message text/caption
|
|
reply_markup: Inline keyboard markup
|
|
image_path: Optional path to image file
|
|
parse_mode: Parse mode for text (default 'HTML')
|
|
"""
|
|
current_message = query.message
|
|
has_photo = bool(current_message.photo)
|
|
|
|
if image_path:
|
|
# Get or upload image
|
|
cached_file_id = await api_client.get_cached_image(image_path)
|
|
|
|
if not cached_file_id and os.path.exists(image_path):
|
|
# Upload new image
|
|
try:
|
|
with open(image_path, 'rb') as img_file:
|
|
temp_msg = await current_message.reply_photo(
|
|
photo=img_file,
|
|
caption=text,
|
|
reply_markup=reply_markup,
|
|
parse_mode=parse_mode
|
|
)
|
|
if temp_msg.photo:
|
|
cached_file_id = temp_msg.photo[-1].file_id
|
|
await api_client.cache_image(image_path, cached_file_id)
|
|
# Delete old message to keep chat clean
|
|
try:
|
|
await current_message.delete()
|
|
except:
|
|
pass
|
|
return
|
|
except Exception as e:
|
|
logger.error(f"Error uploading image: {e}")
|
|
cached_file_id = None
|
|
|
|
if cached_file_id:
|
|
# Check if current message has same photo
|
|
if has_photo:
|
|
current_file_id = current_message.photo[-1].file_id
|
|
if current_file_id == cached_file_id:
|
|
# Same image, just edit caption
|
|
try:
|
|
await query.edit_message_caption(
|
|
caption=text,
|
|
reply_markup=reply_markup,
|
|
parse_mode=parse_mode
|
|
)
|
|
return
|
|
except BadRequest as e:
|
|
if "Message is not modified" in str(e):
|
|
return
|
|
else:
|
|
# Different image - use edit_message_media for smooth transition
|
|
try:
|
|
media = InputMediaPhoto(
|
|
media=cached_file_id,
|
|
caption=text,
|
|
parse_mode=parse_mode
|
|
)
|
|
await query.edit_message_media(
|
|
media=media,
|
|
reply_markup=reply_markup
|
|
)
|
|
return
|
|
except Exception as e:
|
|
logger.error(f"Error editing message media: {e}")
|
|
|
|
# Current message has no photo - need to delete and send new
|
|
if not has_photo:
|
|
try:
|
|
await current_message.delete()
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
await current_message.reply_photo(
|
|
photo=cached_file_id,
|
|
caption=text,
|
|
reply_markup=reply_markup,
|
|
parse_mode=parse_mode
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error sending cached image: {e}")
|
|
else:
|
|
# No image requested
|
|
if has_photo:
|
|
# Current message has photo, need to delete and send text-only
|
|
try:
|
|
await current_message.delete()
|
|
except:
|
|
pass
|
|
await current_message.reply_html(text=text, reply_markup=reply_markup)
|
|
else:
|
|
# Both text-only, just edit
|
|
try:
|
|
await query.edit_message_text(text=text, reply_markup=reply_markup, parse_mode=parse_mode)
|
|
except BadRequest as e:
|
|
if "Message is not modified" not in str(e):
|
|
await current_message.reply_html(text=text, reply_markup=reply_markup)
|