nickoala / telepot

Python framework for Telegram Bot API
MIT License
2.43k stars 478 forks source link

Editing message sent once inline_query article has been chosen. #423

Closed ghost closed 5 years ago

ghost commented 5 years ago

When using an inline bot it returns article(s). Once an article has been selected by the user; a message is returned based on this code: articles = [{'type': 'article', 'id': 'abc', 'title': query_string, 'message_text': 'Some Message here'}] I want to be able to edit this message sent.

I have been looking at the documentation and see the message_identifier method. It says msg is expected to be chat or choson_inline_result. However, so far I have not been successful in it's usage.

One example I have tried: async def on_chosen_inline_result(self, msg): inline_message_id = telepot.message_identifier(msg)

Can someone explain to me what I'm doing wrong?

Thanks!

nickoala commented 5 years ago

It's been a while since I made all that stuff (and I am not actively maintaining them), so my memory is a little fuzzy. I suspect you cannot edit such a message, but I may be wrong.

Can you help me by trying out the file inline.py in the examples/inline directory? It is a simple example of inline query, and prints out the ChosenInlineResult when user makes a choice. Can you tell me what the ChosenInlineResult looks like?

The key is whether it contains the field inline_message_id. If it does not, then editing would not be possible. Even if it does, I am not sure it points to an editable message. Let's see if the field inline_message_id is present. If not, we can be sure it cannot be edited.

nickoala commented 5 years ago

Reading through the Bot API docs gives me some clues ...

ChosenInlineResult's inline_message_id field is "... available only if there is an inline keyboard attached to the message", which led me to all those InlineQueryResult, all of which has an optional field reply_markup which specifies an inline keyboard.

In other words, in order to get an inline_message_id which enables you to edit a message, you first have to give a reply_markup to an InlineQueryResult. If you do that, the ChosenInlineResult (after user making a choice) should contain an inline_message_id. You can extract it using telepot.message_identifier() and use that to edit the message later:

def on_chosen_inline_result(self, msg):
    self.msgid = telepot.message_identifier(msg)

# some time later ...
bot.editMessageText(self.msgid, ...)

I also want to remind you that the class telepot.helper.Editor is designed to help you in exactly these cases:

def on_chosen_inline_result(self, msg):
    self.editor = telepot.helper.Editor(self.bot, msg)

# some time later ...
self.editor.editMessageText(...)

All these suggestions come with the caveat that my memory is still fuzzy and I may be wrong. In any case, it's good to try the simple program examples/inline/inline.py to see exactly what ChosenInlineResult you get back.

Good luck.

ghost commented 5 years ago

Hey @nickoala

I executed the inlinea.py from the examples.

The message itself is as follows: {'from': {'first_name': 'name here', 'id': 531542910, 'is_bot': False, 'language_code': 'en-GB', 'username': 'username here'}, 'location': {'latitude': float here, 'longitude': float here}, 'query': 'test', 'result_id': 'abc'}

By the ChosenInlineResult I assume you are referring to the print statement: 531542910 : Chosen Inline Result: abc 531542910 test

Dextroz.

EDIT: The ChosenInlineResult is: ('abc', 531542910, 'testing') a tuple as expected.

ghost commented 5 years ago

@nickoala I have used the following code which still raises a ValueError:

class InlineHandler(InlineUserHandler, AnswererMixin):
    def __init__(self, *args, **kwargs):
        super(InlineHandler, self).__init__(*args, **kwargs)

    def on_inline_query(self, msg):
        def compute_answer():
            query_id, from_id, query_string = telepot.glance(
                msg, flavor='inline_query')
            print(self.id, ':', 'Inline Query:',
                  query_id, from_id, query_string)

            articles = [InlineQueryResultArticle(id='abc', title=query_string, reply_markup=None, input_message_content=InputTextMessageContent(message_text='Working...'))]

            return articles

        self.answerer.answer(msg, compute_answer)

    def on_chosen_inline_result(self, msg):
        self.msgid = telepot.message_identifier(msg)
        print(self.msgid)
ghost commented 5 years ago

In other words, in order to get an inline_message_id which enables you to edit a message, you first have to give a reply_markup to an InlineQueryResult. If you do that, the ChosenInlineResult (after user making a choice) should contain an inline_message_id.

Adding a simple InlineKeyboardButton and doing as you said has solved the issue. Doing this obtains the inline_message_id. Thanks for the help @nickoala.