2025, Oct 22 12:46
Telegram Bot API में चैट हिस्ट्री क्यों नहीं मिलती और Python बॉट में टाइमआउट से कैसे बचें
सीखें कि Telegram Bot API चैट हिस्ट्री क्यों नहीं देता, Python में get_updates को नेस्ट करना कैसे connection pool टाइमआउट कराता है, TDLib और सही पोलिंग से हल पाएं
Python में Telegram बॉट बनाते समय, अक्सर पिछली चैट संदेशों तक पहुंचने की जरूरत पड़ती है। पहली नजर में यह सरल लगता है, लेकिन Telegram Bot API चैट हिस्ट्री उपलब्ध नहीं कराती। इसे दरकिनार करने की कोशिशें अक्सर प्रदर्शन संबंधी समस्याएं पैदा करती हैं — जैसे पोलिंग के दौरान कनेक्शन पूल खत्म होना और TimedOut त्रुटियां आना।
समस्या का उदाहरण
नीचे दिया गया हैंडलर स्ट्रक्चर दिखाता है कि यह दिक्कत आमतौर पर कैसे सामने आती है। कोड एक इनकमिंग अपडेट प्रोसेस करता है और फिर हैंडलर के अंदर से दोबारा get_updates बुला देता है — यानी पोलिंग पहले से सक्रिय रहती है और उसी दौरान सर्वर पर अतिरिक्त रिक्वेस्ट जाती रहती हैं।
class ChatBotRunner:
    def __init__(self) -> None:
        self.api_key = os.getenv("TELEGRAM_BOT_TOKEN")
        self.app = ApplicationBuilder().token(self.api_key).connection_pool_size(20).build()
    def start(self) -> None:
        self._wire_handlers()
        self.app.run_polling()
        log.info("BOT STARTED")
    def _wire_handlers(self):
        self.app.add_handler(MessageHandler(filters=filters.TEXT, callback=menu_handler))
async def menu_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user = await load_user(update)
    log.error(user.phase)
    match user.phase:
        case Phase.intro:
            log.error(update.message.text)
            log.error(update.message)
            batch = await update._bot.get_updates()
            for item in batch:
                log.error(item)
                log.error(item.message)
                last_id = item.update_id
असल में क्या हो रहा है और गड़बड़ी क्यों होती है
बॉट का connection pool size 20 पर सेट है। run_polling पहले ही अपडेट ला रहा होता है, उसी बीच हैंडलर से get_updates की एक और कॉल हो जाती है। यह अतिरिक्त पोलिंग, पिछली अपडेट्स को प्रोसेस करते समय भी रिक्वेस्ट भेजती रहती है। पर्याप्त समवर्ती इंटरैक्शन होने पर उपलब्ध कनेक्शन जल्दी खत्म हो जाते हैं, और नतीजा TimedOut त्रुटि होता है — यानी पूल के सारे कनेक्शन व्यस्त हैं और अनुरोध भेजा ही नहीं गया।
क्या बॉट चैट हिस्ट्री ला सकता है?
नहीं। Telegram Bot API किसी चैट की पुरानी संदेशों को पाने का तरीका नहीं देता। यदि आपको संदेशों की हिस्ट्री चाहिए, तो TDLib आधारित क्लाइंट API अपनानी होगी, जैसे tdlib। यह तरीका बॉट पोलिंग से अलग काम करता है और फुल क्लाइंट एक्सेस के लिए डिज़ाइन किया गया है, जिसमें चैट हिस्ट्री भी शामिल है।
कनेक्शन पूल टाइमआउट कैसे ठीक करें
सबसे सीधा समाधान है नेस्टेड पोलिंग से बचना। आमतौर पर हैंडलर्स के भीतर मैन्युअली get_updates कॉल करने की आवश्यकता नहीं होती, क्योंकि run_polling पहले से ही अपडेट फ्लो संभाल रहा होता है।
class ChatBotRunner:
    def __init__(self) -> None:
        self.api_key = os.getenv("TELEGRAM_BOT_TOKEN")
        self.app = ApplicationBuilder().token(self.api_key).connection_pool_size(20).build()
    def start(self) -> None:
        self._wire_handlers()
        self.app.run_polling()
        log.info("BOT STARTED")
    def _wire_handlers(self):
        self.app.add_handler(MessageHandler(filters=filters.TEXT, callback=menu_handler))
async def menu_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user = await load_user(update)
    log.error(user.phase)
    match user.phase:
        case Phase.intro:
            log.error(update.message.text)
            log.error(update.message)
            # यहां get_updates() को नेस्ट करके कॉल न करें
            # सिर्फ मौजूदा अपडेट को ही संभालें
यह क्यों महत्वपूर्ण है
Telegram Bot API और क्लाइंट API के फर्क को समझना समय बचाता है और बेनतीजा प्रयासों से बचाता है। बॉट इंटरफेस इवेंट-ड्रिवन है और हिस्ट्री उपलब्ध नहीं कराता; हैंडलर्स के भीतर मैन्युअल पोलिंग जोड़ने से सिर्फ लोड बढ़ता है और समवर्ती परिस्थितियों में संसाधन जल्दी खत्म हो जाते हैं। जिम्मेदारियों की साफ़ सीमा प्रदर्शन को पूर्वानुमेय बनाती है और ऑपरेशनल आश्चर्य कम करती है।
मुख्य बातें
यदि आपको पुराने संदेश चाहिए, तो Bot API उन्हें नहीं देगा; इसके बजाय TDLib जैसी क्लाइंट API का उपयोग करें। बॉट के लिए, अपडेट्स को run_polling पर छोड़ें और हैंडलर्स के भीतर get_updates कॉल करने से बचें। इससे कनेक्शन पूल संतृप्त होने से बचता है और लोड में भी बॉट प्रतिक्रियाशील रहता है।
यह लेख StackOverflow पर प्रश्न (लेखक: Konstantinos) और mint_tube के उत्तर पर आधारित है।