无法使用异步功能从 Telegram Media Group 下载多个图像

问题描述 投票:0回答:1

这个问题是之前提出的问题的后续问题这里

我需要帮助来尝试修改我当前仅用于下载 1 个图像的代码部分。

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)

我使用了之前的post的答案中的逻辑。

要执行此操作:

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)

我在下载图像时仍然遇到问题,因为逻辑不正确,并且非常感谢您提供的任何指导或建议来帮助我成功下载多个图像。

python-3.x telegram telegram-bot python-telegram-bot telegram-api
1个回答
0
投票

首先。请更改:

        if update.message.media_group_id != group_id:
            media_paths = download_all_photos(context)

致:

        if update.message.media_group_id != group_id:
            media_paths = await download_all_photos(context)

仔细观察。我不明白这个代码:

        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

您可以跳过它,直接调用下载吗?我的意思是 -

update.message
在这段代码中没有改变,所以为什么要等待,而且...如果是这样 -
group_id
...media_group_id
相同,所以
download_all_photos
不会被触发。

© www.soinside.com 2019 - 2024. All rights reserved.