pythonbotstelegramtelethon

How to capture the updated (or new) message after clicking an inline button in Telethon?


I’m trying to automate a Telegram workflow using Telethon in Python. I interact with a third-party Telegram bot as a normal user account. The bot has inline buttons labeled “⬅”, “1/7”, “➡” to navigate different pages within a single message.

Issue:

After I click the inline button (either via GetBotCallbackAnswerRequest or await msg.click(...)), I want to retrieve the updated or new message text. However, Telethon doesn’t automatically return the updated text from the callback answer, but instead return always the same first message.

`

        while True:
            try:
                # Wait for the next response. Use a short timeout (e.g. 3s)
                msg = await conv.get_response(timeout=3)
                #print(msg.stringify())
                # Append the message text (or the entire Message object if you want)
                all_bot_replies.append(msg.text)
                print(msg.text)
                """
                if msg.reply_markup is not None:
                    for row in msg.reply_markup.rows:
                        if len(row.buttons) > 2:
                            button = row.buttons[2]
                            #print(msg.stringify())

                            # Click the button
                            await msg.click(2)
                            await msg.click(2)
                            update_event = await conv.wait_event(events.MessageEdited)
                            print("quaaaaaaaaaaa", update_event)
                """
                try:
                    for row in msg.reply_markup.rows:
                        button = []
                        button.append(row.buttons)
                        try:
                            if button[0][2]:
                                btn = button[0][2]
                                page = button[0][1].text[0]
                                finalpage = button[0][1].text[-1]
                                callback_data = btn.data
                                
                                
                                for i in range(int(page), int(finalpage)+1):
                                    print("stom qua")
                                # con la callback clicco il bottone
                                    await client(GetBotCallbackAnswerRequest(
                                        peer=msg.chat.id,  
                                        msg_id=msg.id,     
                                        data=callback_data
                                    ))
                                    
                                                           
                        except IndexError:
                            pass    
                except AttributeError:
                    pass
            except asyncio.TimeoutError:
                # No more messages arrived in 3 seconds -> done
                break

    # Store the list of replies for this email
    results[email] = all_bot_replies`

Im expecting to have the possibility to print the messages of the other pages.


Solution

  • firstly, you can't loop a click, callback data changes upon click. get_response only await a single response to your initial sent message, it won't return anything else. it just errors on next call in iteration.

    either fetch the updated message yourself in each iteration, roughly as:

    all_bot_replies = []
    
    msg = await conv.get_response(...)
    
    while True:
        is_next_left = len(msg.buttons) == 3
    
        all_bot_replies.append(msg.text)
        print(msg.text)
    
        if not is_next_left:
            break 
    
        await msg.click(2)
        msg = await client.get_messages(msg.chat_id, ids=msg.id)
    

    Or design it more efficiently using two separate event handlers than context based approach to avoid making get_messages calls, where you listen to events.MessageEdited that is emitted upon the click from that bot, it's on you to do if it matters for sake of simplicity.