I’m working on a Telegram bot using Python and the python-telegram-bot library. The bot processes and saves media files (images and videos) along with text content from messages in a group chat. However, I am facing issues with how the bot handles multiple media files within a single message.
Issues:
Multiple Media Files Handling: When a message contains multiple media files (e.g., several images and videos), the handle_message function is called separately for each media file. This means that if a message includes 3 images and 2 videos, the function is invoked 5 times—once for each file.
Metadata Overwriting: Each call to handle_message processes and saves metadata and media files individually. This results in the metadata file being overwritten multiple times, which causes the loss of previously saved metadata and text content.
Current code:
#parses and returns meta data
def parse_message_metadata(message):
metadata = {
"message_id": message.message_id,
"date": {
"year": message.date.year,
"month": message.date.month,
"day": message.date.day,
"hour": message.date.hour,
"minute": message.date.minute,
"second": message.date.second
},
"content": {
"text": message.caption if message.caption else message.text
},
"user": {
"id": message.from_user.id
},
"chat_id": message.chat_id,
"media": {}
}
# Save photo object
if message.photo:
slicing = len(message.photo) // 3 # Adjust slicing logic as needed
img_list = message.photo[-slicing:]
metadata["media"]["type"] = "photo"
metadata["media"]["photo_object"] = img_list
# print(f'ggggg{metadata}')
# Save video object
if message.video:
metadata["media"]["type"] = "video"
metadata["media"]["video_object"] = message.video
# print(f'ffffff{metadata}')
return metadata
Note i index the last 3 elements of the Photosize object in parse_message_metadata() as they are the highest rez images.
# grabs sent messages in the group and saves to a file
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
metadata = parse_message_metadata(update.message)
if metadata['media'].get('photo_object'):
for i in metadata['media']['photo_object']:
file = await context.bot.get_file(i.file_id)
file_path = os.path.join(IMAGE_DIR,f"downloaded_image_{i.file_id}.jpg")# save to directory
await file.download_to_drive(file_path)
if metadata['media'].get('video_object'):
video = metadata['media']['video_object']
file = await context.bot.get_file(video.file_id)
file_path = os.path.join(VID_DIR, f"downloaded_video_{video.file_id}.mp4") # save to directory
await file.download_to_drive(file_path)
# del metadata['media']
with open("metadata", "w") as f:
json.dump(metadata,f, indent=4, default=str)
def main():
try:
application = Application.builder().token(TOKEN).build()
application.add_handler(MessageHandler(filters.TEXT | filters.PHOTO | filters.VIDEO, handle_message))
# Add a command handler for the /send command
application.add_handler(CommandHandler("send", lambda update, context: asyncio.create_task(send_message_to_group())))
# Start the application (assuming this runs the bot and starts handling updates)
application.run_polling()
except KeyboardInterrupt:
print("Bot stopped by keyboard interrupt")
Current Behavior:
Metadata Parsing: The parse_message_metadata function extracts metadata for each piece of media and text. However, it is invoked separately for each media file, which results in multiple metadata files being created or overwritten.
Handling Messages: The handle_message function downloads images and videos, saving metadata and text content. The issue is that it processes each media file separately, leading to metadata and text content being overwritten.
Problem:
My media gets downloaded correctly, but the handle_message function seems to be invoked multiple times for a single message containing multiple pieces of media (e.g., three images and two videos).
What I Have Tried:
Adjusting the message filters to combine media handling.
Using the Telethon library to group messages.
How can I ensure that the handle_message function processes all media in a single message at once, rather than being invoked separately for each piece of media?