This question is a follow up from this question asked earlier here
I need help in trying to modify this code section which I am currently using to download just 1 image.
async def handle_s_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
try:
text = update.message.text or update.message.caption
if text is None:
logger.error("Received message with no text or caption.")
return
if not text.startswith('/s '):
logger.error("Message does not start with /s command.")
return
# Prepare text for Twitter (second Twitter) and Telegram
text_for_second_twitter = text[3:].strip() # Remove /s prefix for second Twitter
text_for_telegram = text[3:].strip() # Remove /s prefix for Telegram
# Check message length
if len(text_for_second_twitter) > 279:
over_limit = len(text_for_second_twitter) - 279
await context.bot.send_message(
chat_id=BOT_CHANNEL_ID,
text=f"Message too long! Length: {len(text_for_second_twitter)} characters, Over limit by: {over_limit} characters."
)
logger.info(f"Message too long: Length {len(text_for_second_twitter)}, Over limit by: {over_limit}")
return
# Other settings
chat_id = update.message.chat.id
message_id = update.message.message_id
reply_to_message_id = update.message.reply_to_message.message_id if is_reply(update) else None
logger.debug(f"Processed text for second Twitter: {text_for_second_twitter}")
logger.debug(f"Processed text for Telegram: {text_for_telegram}")
media_path = None
caption = None
if update.message.photo:
file_id = update.message.photo[-1].file_id
file = await context.bot.get_file(file_id)
media_path = f"photo_{message_id}.jpg"
await file.download_to_drive(media_path)
caption = update.message.caption
logger.debug(f"Downloaded photo with ID: {file_id}, saved as: {media_path}")
if caption and caption.startswith('/s '):
caption = caption[3:].strip()
else:
logger.debug("No photo found in the message")
tweet_client_v2 = client_V2_swing
tweet_client_v1 = client_V1_swing
if not is_valid_json_file(BOT_TO_SECOND_TWITTER_JSON):
logger.error(f"Invalid JSON file: {BOT_TO_SECOND_TWITTER_JSON}")
return
data = load_tracking_data(BOT_TO_SECOND_TWITTER_JSON) or {}
logger.debug(f"Loaded data: {data}")
bot_to_public_data = load_tracking_data(BOT_TO_PUBLIC_JSON) or {}
logger.debug(f"Loaded bot_to_public_data: {bot_to_public_data}")
public_message_id = bot_to_public_data.get(str(reply_to_message_id)) if reply_to_message_id else None
logger.debug(f"Public message ID: {public_message_id}")
tweet_id = None
try:
if media_path:
tweet_id = post_to_twitter(
tweet_client_v2, tweet_client_v1,
text=text_for_second_twitter, # Post without /s prefix
media_path=media_path,
in_reply_to_tweet_id=data.get(str(reply_to_message_id), {}).get('tweet_id') if reply_to_message_id else None
)
logger.debug(f"Tweet ID after posting: {tweet_id}")
with open(media_path, 'rb') as photo_file:
public_msg = await context.bot.send_photo(
chat_id=PUBLIC_CHANNEL_ID,
photo=photo_file,
caption=text_for_telegram, # Ensure caption is used correctly
reply_to_message_id=public_message_id
)
logger.info(f"Telegram: Posted photo with message ID {public_msg.message_id}")
os.remove(media_path)
else:
tweet_id = post_to_twitter(
tweet_client_v2, tweet_client_v1,
text=text_for_second_twitter, # Post without /s prefix
in_reply_to_tweet_id=data.get(str(reply_to_message_id), {}).get('tweet_id') if reply_to_message_id else None
)
logger.debug(f"Tweet ID after posting: {tweet_id}")
public_msg = await context.bot.send_message(
chat_id=PUBLIC_CHANNEL_ID,
text=text_for_telegram,
reply_to_message_id=public_message_id
)
logger.info(f"Telegram: Posted message with ID {public_msg.message_id}")
bot_to_public_data[str(message_id)] = public_msg.message_id
save_tracking_data(BOT_TO_PUBLIC_JSON, bot_to_public_data)
logger.info(f"Updated bot_to_public.json with bot message ID {message_id} and public message ID {public_msg.message_id}")
data[str(message_id)] = {
'tweet_id': tweet_id,
'reply_to_message_id': reply_to_message_id
}
save_tracking_data(BOT_TO_SECOND_TWITTER_JSON, data)
logger.info(f"Updated JSON with message ID {message_id} and tweet ID {tweet_id}")
except Exception as e:
logger.error(f"Error during processing: {e}", exc_info=True)
except Exception as e:
logger.error(f"Handling /s command error: {e}", exc_info=True)
I used this logic from the answer to an earlier post.
To do this:
group_id = None
urls = []
async def download_all_photos(context: ContextTypes.DEFAULT_TYPE):
media_paths = []
for download_url, file_name, file_id in urls:
try:
# Log the full download URL
full_download_url = f"{download_url}"
logger.info(f'Downloading photo from URL: {full_download_url}')
# Download the photo using the download URL
response = requests.get(full_download_url)
response.raise_for_status() # Check if the download was successful
with open(file_name, 'wb') as f:
f.write(response.content)
media_paths.append(file_name)
logger.info(f'Downloaded photo successfully with file_id: {file_id}')
except Exception as e:
logger.error(f'Error downloading photo with file_id {file_id}: {e}')
logger.info(f'All downloaded media paths: {media_paths}')
return media_paths
async def handle_s_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
global group_id, urls
try:
text = update.message.text or update.message.caption
if text is None or not text.startswith('/s '):
return
# Prepare text for Twitter (second Twitter)
text_for_second_twitter = text[3:].strip() # Remove /s prefix
# Check message length
if len(text_for_second_twitter) > 279:
over_limit = len(text_for_second_twitter) - 279
await context.bot.send_message(
chat_id=BOT_CHANNEL_ID,
text=f"Message too long! Length: {len(text_for_second_twitter)} characters, Over limit by: {over_limit} characters."
)
return
media_path = None
caption = None
if update.message.photo:
file_id = update.message.photo[-1].file_id
file_info = await context.bot.get_file(file_id)
download_url = file_info.file_path
file_name = f'photo_{update.message.message_id}_{file_id}.jpg'
urls.append([download_url, file_name, file_id])
if group_id is None and update.message.media_group_id:
group_id = update.message.media_group_id
# Wait to see if there are more photos
await asyncio.sleep(2)
if update.message.media_group_id != group_id:
media_paths = download_all_photos(context)
group_id = None
urls.clear()
# Upload all media to Twitter
media_ids = []
for path in media_paths:
media = client_V1_swing.media_upload(filename=path)
media_ids.append(media.media_id)
# Post tweet with multiple images
response = client_V2_swing.create_tweet(
text=text_for_second_twitter,
media_ids=media_ids
)
logger.info(f"Tweet posted: {response.data['id']}")
tweet_id = response.data['id']
# Optionally, send to Telegram as well
with open(media_paths[0], 'rb') as photo_file:
public_msg = await context.bot.send_photo(
chat_id=PUBLIC_CHANNEL_ID,
photo=photo_file,
caption=text_for_second_twitter
)
logger.info(f"Telegram: Posted photo with message ID {public_msg.message_id}")
# Cleanup downloaded files
for path in media_paths:
os.remove(path)
except Exception as e:
logger.error(f"Handling /s command error: {e}", exc_info=True)
I'm still having trouble downloading the images as the logic is not right and would greatly appreciate any guidance or suggestions you could offer to help me download multiple images successfully.
First. Please change:
if update.message.media_group_id != group_id:
media_paths = download_all_photos(context)
To:
if update.message.media_group_id != group_id:
media_paths = await download_all_photos(context)
Looking closer. I don't get this code:
if group_id is None and update.message.media_group_id:
group_id = update.message.media_group_id
# Wait to see if there are more photos
await asyncio.sleep(2)
if update.message.media_group_id != group_id:
media_paths = await download_all_photos(context)
group_id = None
Could you just skip it, and just call download? I mean - update.message
is not changing in this code, so why to wait, and... if so - group_id
is same as ...media_group_id
so download_all_photos
is not triggered.