基于Python-Flask实现Telegram Bot服务器端下载用户发送大视频及API方法选型问询
Handling Large Video Downloads (350MB+) in a Flask-Based Telegram Bot
Hey there! Great question—when dealing with large video files (350MB+) in your Flask-powered Telegram Bot, you can’t rely on naive download methods (like loading the entire file into memory at once). Here’s the right approach using Telegram’s Bot API:
Core Method: getFile + Streamed Download
The key is to use Telegram’s getFile API endpoint to retrieve a temporary download URL for the file, then perform a streamed, chunked download to your server. This avoids memory overload and timeouts that come with pulling huge files in one go.
Step-by-Step Breakdown
- Extract the File ID: When a user sends a video, your Flask webhook will receive an update containing the video object. Grab its
file_idfrom the payload. - Fetch File Metadata: Call the
getFileAPI with thefile_idto get thefile_path(this is the path to the file on Telegram’s servers). - Construct Download URL: Build the full download URL using your bot token and the
file_path. - Stream the Download: Use a library like
requeststo download the file in small chunks, writing each chunk to disk immediately instead of storing the whole file in memory.
Example Flask Code
Here’s a minimal working example using Flask and requests:
import requests from flask import Flask, request app = Flask(__name__) BOT_TOKEN = "your_actual_bot_token_here" @app.route('/telegram-webhook', methods=['POST']) def handle_webhook(): update = request.get_json() # Check if the update contains a video message if not update.get('message') or not update['message'].get('video'): return 'OK' video_data = update['message']['video'] file_id = video_data['file_id'] chat_id = update['message']['chat']['id'] # Step 1: Get file details from Telegram API get_file_endpoint = f"https://api.telegram.org/bot{BOT_TOKEN}/getFile" file_info = requests.get(get_file_endpoint, params={'file_id': file_id}).json() if not file_info['ok']: # Send error message to user requests.post( f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage", data={'chat_id': chat_id, 'text': "Failed to retrieve video details. Please try again."} ) return 'OK' # Step 2: Build the direct download URL file_path = file_info['result']['file_path'] download_url = f"https://api.telegram.org/file/bot{BOT_TOKEN}/{file_path}" # Step 3: Stream download the large video try: with open(f"downloaded_video_{chat_id}.mp4", 'wb') as output_file: with requests.get(download_url, stream=True, timeout=300) as response: response.raise_for_status() # Download in 8KB chunks (adjust size based on your server's memory) for chunk in response.iter_content(chunk_size=8192): output_file.write(chunk) # Notify user of success requests.post( f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage", data={'chat_id': chat_id, 'text': "Your large video has been downloaded successfully!"} ) except Exception as e: # Handle download errors (timeouts, network issues, etc.) requests.post( f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage", data={'chat_id': chat_id, 'text': f"Download failed: {str(e)}"} ) return 'OK' if __name__ == '__main__': # For production, use a proper WSGI server like Gunicorn instead of Flask's dev server app.run(host='0.0.0.0', port=5000, debug=False)
Critical Notes for Large Files
- Streamed Downloads are Non-Negotiable: Using
stream=Trueanditer_contentensures you don’t load the entire 350MB+ file into RAM, which would crash most servers. - Timeout Settings: Adjust the
timeoutparameter inrequests.getto account for longer download times (5 minutes is a safe start for large files). - Production Server: Flask’s built-in development server isn’t designed for heavy traffic or long-running downloads. Use Gunicorn, uWSGI, or a similar WSGI server in production.
- File Expiry: Telegram’s download URLs are only valid for 1 hour, so process the file immediately after retrieving the URL.
- Error Handling: Add robust error catching for network issues, disk space limits, and Telegram API failures—your users will appreciate clear feedback.
内容的提问来源于stack exchange,提问作者Negar




