如何在Python中为Telegram Bot发送的图片应用ForceReply并获取回复?
Fixing Telegram Bot ForceReply and Targeted Reply Retrieval Issues
Looks like you're hitting two common pitfalls with the Telegram Bot API—let's break them down and fix each one step by step.
1. Fixing the ForceReply Not Showing Up
Your current code has two key issues causing ForceReply to fail:
- You’re passing
'ForceReply'as a raw string instead of the structured JSON object the API expects - You’re putting
reply_markupin thefilesdictionary, but it belongs in form data (not part of the file upload payload)
The Telegram API requires reply_markup to be a JSON string defining the ForceReply configuration. Here's the corrected code to send your photo with working ForceReply:
import requests import json # Replace these with your actual values UserID = "your_user_id_here" BOT_API_TOKEN = "your_bot_token_here" send_photo_url = f"https://api.telegram.org/bot{BOT_API_TOKEN}/sendPhoto" # Build the ForceReply markup as a serialized JSON string force_reply_markup = json.dumps({ "force_reply": True, "selective": True # Optional but recommended: only forces reply to this specific message }) # Files only contains the photo file; other parameters go in the data dict files = {'photo': open("/home/preetham/Downloads/selenium/cap.jpg", 'rb')} data = { "chat_id": UserID, "reply_markup": force_reply_markup } # Send the request and capture the sent message's ID (we'll need this later) status = requests.post(send_photo_url, files=files, data=data) if status.ok: sent_photo_message_id = status.json()['result']['message_id'] print(f"Photo sent successfully! Message ID: {sent_photo_message_id}") else: print(f"Failed to send photo: {status.text}")
This will now properly trigger the "Reply" prompt tied directly to your sent photo.
2. Retrieving the Correct Reply to the Photo
Your polling code has two critical flaws:
- It doesn’t use the
offsetparameter, so it keeps fetching old, already processed messages - It doesn’t verify if the reply is actually in response to your photo (it just grabs the last message in the history)
Here's the fixed polling logic that addresses both issues:
import time get_updates_url = f"https://api.telegram.org/bot{BOT_API_TOKEN}/getUpdates" offset = 0 # Tracks the last processed update to avoid re-reading old messages reply_string = "" # Variable to store the user's reply while True: try: # Fetch only new updates using the offset parameter response = requests.get(get_updates_url, params={"offset": offset, "timeout": 30}) response.raise_for_status() # Throw an error if the API request fails updates = response.json()['result'] for update in updates: update_id = update['update_id'] # Update offset so we skip this update next time offset = update_id + 1 # Check if this update is a message that's a reply to another message if 'message' in update and 'reply_to_message' in update['message']: incoming_message = update['message'] # Verify the reply is targeting our sent photo if incoming_message['reply_to_message']['message_id'] == sent_photo_message_id: # Ensure the reply is text (handle cases where user sends stickers/etc.) if 'text' in incoming_message: reply_string = incoming_message['text'] print(f"Received reply to your photo: {reply_string}") exit() # Exit loop once we get the correct reply time.sleep(1) # Avoid hitting Telegram's API rate limits except Exception as e: print(f"Error fetching updates: {str(e)}") time.sleep(2)
Key Improvements:
- Offset Management: By setting
offsettoupdate_id + 1, we tell the API to only send us updates we haven’t processed yet—no more old message repeats. - Reply Validation: We check that the message is a reply, and that it’s replying to the exact photo message we sent (matching the
sent_photo_message_idwe captured earlier). - Error Handling: Added basic error handling and rate limiting to make the polling more robust.
Quick Notes:
- Fix the typo in your
getUpdatesURL: it should start withbot{BOT_API_TOKEN}(you missed thebotprefix and had a mismatched bracket). - Use
requests.getforgetUpdatesinstead ofpost—it’s the proper HTTP method for fetching data.
内容的提问来源于stack exchange,提问作者preethh




